Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions packages/cli/src/commands/event/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,19 @@ export function parsePositionalArgs(args: string[]): ParsedPositionalArgs {
};
}

// Detect issue short ID as second arg (e.g., "my-org/my-project BRUNCHIE-APP-29").
// Auto-redirect to that issue's latest event instead of treating the short
// ID as an event hex ID (which would fail validation).
if (looksLikeIssueShortId(second)) {
const extraEventIds = args.length > 2 ? args.slice(2) : undefined;
return {
eventId: LATEST_EVENT_SENTINEL,
targetArg: first,
issueShortId: second,
extraEventIds,
};
}
Comment thread
jared-outpost[bot] marked this conversation as resolved.

// Two or more args - first is target, second is event ID.
// Any additional args are extra event IDs (from newline-separated input).
const extraEventIds = args.length > 2 ? args.slice(2) : undefined;
Expand Down Expand Up @@ -888,9 +901,12 @@ async function resolveIssueShortcut(
// alongside a hex event ID. Resolve the issue to get org/project.
if (issueShortId) {
// Use the explicit org from the parsed target if available (e.g.,
// "figma/" → org-all with org "figma"), otherwise fall back to
// auto-detection via DSN/env/config.
const explicitOrg = parsed.type === "org-all" ? parsed.org : undefined;
// "figma/" → org-all, or "figma/project" → explicit, both carry the
// org), otherwise fall back to auto-detection via DSN/env/config.
const explicitOrg =
parsed.type === "org-all" || parsed.type === "explicit"
? parsed.org
: undefined;
const resolved = await resolveOrg({ org: explicitOrg, cwd });
if (!resolved) {
throw new ContextError(
Expand Down
39 changes: 39 additions & 0 deletions packages/cli/test/commands/event/view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,45 @@ describe("viewCommand.func", () => {
getLatestEventSpy.mockRestore();
});

test("org/project + short-ID second arg passes explicit org through to resolveOrg", async () => {
// Regression: with an explicit "org/project" target and an issue short ID
// as the second arg, the org must be forwarded to resolveOrg instead of
// being dropped (which would fall back to auto-detection and miss/mishit).
const resolveOrgSpy = vi
.spyOn(resolveTarget, "resolveOrg")
.mockResolvedValue({ org: "my-org" });
const getIssueByShortIdSpy = vi
.spyOn(apiClient, "getIssueByShortId")
.mockResolvedValue({ id: "999", shortId: "CAM-82X" } as never);
const getLatestEventSpy = vi
.spyOn(apiClient, "getLatestEvent")
.mockResolvedValue(sampleEvent);
getSpanTreeLinesSpy.mockResolvedValue({
lines: [],
spans: null,
traceId: null,
success: false,
});

const { context } = createMockContext();
const func = await viewCommand.loader();
await func.call(
context,
{ json: true, web: false, spans: 0 },
"my-org/my-project",
"CAM-82X"
);

expect(resolveOrgSpy).toHaveBeenCalledWith(
expect.objectContaining({ org: "my-org" })
);
expect(getLatestEventSpy).toHaveBeenCalled();

resolveOrgSpy.mockRestore();
getIssueByShortIdSpy.mockRestore();
getLatestEventSpy.mockRestore();
});

test("logs normalized slug warning when underscores present", async () => {
getEventSpy.mockResolvedValue(sampleEvent);
getSpanTreeLinesSpy.mockResolvedValue({
Expand Down
Loading