Skip to content

Commit 9435e03

Browse files
sergicalclaude
andcommitted
fix: address remaining review findings and lint errors
- Fix lint: use Number.POSITIVE/NEGATIVE_INFINITY, reorder imports - Fix formatTimestamp treating unix seconds as milliseconds (showed 1970 dates) - Preserve --query filter in pagination hints - Surface truncation warning when transcript exceeds pagination limit - Make view command org optional with resolveOrg fallback - Register ai-conversations commands in ORG_ONLY_COMMANDS for completions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3b23040 commit 9435e03

6 files changed

Lines changed: 51 additions & 15 deletions

File tree

src/commands/ai-conversations/list.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ export const listCommand = buildListCommand("ai-conversations", {
194194
});
195195

196196
const parts: string[] = [];
197+
if (flags.query) {
198+
parts.push(`-q "${flags.query}"`);
199+
}
197200
appendPeriodHint(parts, flags.period, DEFAULT_PERIOD);
198201
const flagSuffix = parts.length > 0 ? ` ${parts.join(" ")}` : "";
199202

src/commands/ai-conversations/view.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import type { SentryContext } from "../../context.js";
88
import { getConversationSpans } from "../../lib/api-client.js";
99
import { buildCommand } from "../../lib/command.js";
10+
import { ContextError } from "../../lib/errors.js";
1011
import {
1112
buildTranscriptResult,
1213
formatTranscriptResult,
@@ -19,6 +20,7 @@ import {
1920
FRESH_FLAG,
2021
} from "../../lib/list-command.js";
2122
import { withProgress } from "../../lib/polling.js";
23+
import { resolveOrg } from "../../lib/resolve-target.js";
2224

2325
type ViewFlags = {
2426
readonly json: boolean;
@@ -43,8 +45,9 @@ export const viewCommand = buildCommand({
4345
parameters: [
4446
{
4547
placeholder: "org",
46-
brief: "Organization slug",
48+
brief: "Organization slug (optional if auto-detected)",
4749
parse: String,
50+
optional: true,
4851
},
4952
{
5053
placeholder: "conversation-id",
@@ -61,12 +64,31 @@ export const viewCommand = buildCommand({
6164
async *func(
6265
this: SentryContext,
6366
flags: ViewFlags,
64-
org: string,
65-
conversationId: string
67+
orgOrConversationId: string,
68+
maybeConversationId?: string
6669
) {
6770
applyFreshFlag(flags);
71+
const { cwd } = this;
6872

69-
const spans = await withProgress(
73+
let org: string;
74+
let conversationId: string;
75+
76+
if (maybeConversationId) {
77+
org = orgOrConversationId;
78+
conversationId = maybeConversationId;
79+
} else {
80+
const resolved = await resolveOrg({ cwd });
81+
if (!resolved) {
82+
throw new ContextError(
83+
"Organization",
84+
"sentry ai-conversations view <org> <conversation-id>"
85+
);
86+
}
87+
org = resolved.org;
88+
conversationId = orgOrConversationId;
89+
}
90+
91+
const { spans, truncated } = await withProgress(
7092
{
7193
message: "Fetching conversation spans...",
7294
json: flags.json,
@@ -75,6 +97,7 @@ export const viewCommand = buildCommand({
7597
);
7698

7799
const result = buildTranscriptResult(conversationId, org, spans);
100+
result.truncated = truncated;
78101
yield new CommandOutput<TranscriptResult>(result);
79102
},
80103
});

src/lib/api/ai-conversations.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export async function getConversationSpans(
8181
project?: string;
8282
perPage?: number;
8383
} = {}
84-
): Promise<AIConversationSpan[]> {
84+
): Promise<{ spans: AIConversationSpan[]; truncated: boolean }> {
8585
const regionUrl = await resolveOrgRegion(orgSlug);
8686
const pageSchema = z.array(AIConversationSpanSchema);
8787

@@ -115,11 +115,12 @@ export async function getConversationSpans(
115115
}
116116
}
117117

118-
if (cursor) {
118+
const truncated = !!cursor;
119+
if (truncated) {
119120
log.warn(
120121
`Pagination limit reached (${MAX_PAGINATION_PAGES} pages, ${spans.length} spans). Conversation transcript may be incomplete.`
121122
);
122123
}
123124

124-
return spans;
125+
return { spans, truncated };
125126
}

src/lib/complete.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ export const ORG_PROJECT_COMMANDS = new Set([
125125
* @internal Exported for testing only.
126126
*/
127127
export const ORG_ONLY_COMMANDS = new Set([
128+
"ai-conversations list",
129+
"ai-conversations view",
128130
"org view",
129131
"release list",
130132
"release view",

src/lib/formatters/ai-conversations.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ function truncate(value: string, max = 60): string {
2121
return `${value.slice(0, max - 1)}…`;
2222
}
2323

24-
function formatTimestamp(ms: number): string {
25-
if (ms === 0) {
24+
function formatTimestamp(epochSeconds: number): string {
25+
if (epochSeconds === 0) {
2626
return "—";
2727
}
28-
return new Date(ms).toLocaleString();
28+
return new Date(epochSeconds * 1000).toLocaleString();
2929
}
3030

3131
export function formatConversationTable(items: ConversationListItem[]): string {
@@ -338,6 +338,7 @@ export type TranscriptResult = {
338338
projects: string[];
339339
startTimestamp: number;
340340
endTimestamp: number;
341+
truncated?: boolean;
341342
};
342343

343344
export function formatTranscriptResult(result: TranscriptResult): string {
@@ -358,7 +359,13 @@ export function formatTranscriptResult(result: TranscriptResult): string {
358359
"",
359360
];
360361

361-
return [...header, ...result.turns.map(formatTurnHuman)].join("\n");
362+
const sections = [...header, ...result.turns.map(formatTurnHuman)];
363+
if (result.truncated) {
364+
sections.push(
365+
"⚠ Transcript truncated — the conversation exceeds the pagination limit."
366+
);
367+
}
368+
return sections.join("\n");
362369
}
363370

364371
export function buildTranscriptResult(
@@ -381,14 +388,14 @@ export function buildTranscriptResult(
381388
spans.length > 0
382389
? spans.reduce(
383390
(min, s) => Math.min(min, s["precise.start_ts"]),
384-
Infinity
391+
Number.POSITIVE_INFINITY
385392
)
386393
: 0,
387394
endTimestamp:
388395
spans.length > 0
389396
? spans.reduce(
390397
(max, s) => Math.max(max, s["precise.finish_ts"]),
391-
-Infinity
398+
Number.NEGATIVE_INFINITY
392399
)
393400
: 0,
394401
};

src/types/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* Re-exports all types from domain-specific modules.
66
*/
77

8+
// DSN types
9+
export type { DetectedDsn, DsnSource, ParsedDsn } from "../lib/dsn/types.js";
810
// AI Conversations types
911
export type {
1012
AIConversationSpan,
@@ -14,8 +16,6 @@ export {
1416
AIConversationSpanSchema,
1517
ConversationListItemSchema,
1618
} from "./ai-conversations.js";
17-
// DSN types
18-
export type { DetectedDsn, DsnSource, ParsedDsn } from "../lib/dsn/types.js";
1919
// Configuration types
2020
export type {
2121
CachedProject,

0 commit comments

Comments
 (0)