@tryarcanist/cli 0.1.85 → 0.1.87
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +89 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -562,6 +562,50 @@ function normalizeUploadedFileOptions(files) {
|
|
|
562
562
|
return Array.isArray(files) ? files : [files];
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
+
// ../../shared/session/no-change-outcome.ts
|
|
566
|
+
function isNoChangesPromptResult(result) {
|
|
567
|
+
return typeof result === "object" && result !== null && "noChanges" in result && result.noChanges === true;
|
|
568
|
+
}
|
|
569
|
+
function noChangeOutcomeCopy(reason) {
|
|
570
|
+
switch (reason) {
|
|
571
|
+
case "no_diff":
|
|
572
|
+
return {
|
|
573
|
+
state: "no_changes",
|
|
574
|
+
tone: "info",
|
|
575
|
+
title: "Completed without code changes - no PR created.",
|
|
576
|
+
detail: null
|
|
577
|
+
};
|
|
578
|
+
case "no_staged_files":
|
|
579
|
+
return {
|
|
580
|
+
state: "no_changes",
|
|
581
|
+
tone: "info",
|
|
582
|
+
title: "Completed without publishable code changes - no PR created.",
|
|
583
|
+
detail: null
|
|
584
|
+
};
|
|
585
|
+
case "repoless_benchmark":
|
|
586
|
+
return {
|
|
587
|
+
state: "no_changes",
|
|
588
|
+
tone: "info",
|
|
589
|
+
title: "Completed without code changes - no PR created.",
|
|
590
|
+
detail: null
|
|
591
|
+
};
|
|
592
|
+
case "prep_failed":
|
|
593
|
+
return {
|
|
594
|
+
state: "no_change_abnormal",
|
|
595
|
+
tone: "error",
|
|
596
|
+
title: "Finalization failed before changes could be prepared.",
|
|
597
|
+
detail: null
|
|
598
|
+
};
|
|
599
|
+
default:
|
|
600
|
+
return {
|
|
601
|
+
state: "no_change_abnormal",
|
|
602
|
+
tone: "error",
|
|
603
|
+
title: "Completed without code changes, but finalization did not report a clean no-op reason.",
|
|
604
|
+
detail: null
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
565
609
|
// ../../shared/utils/type-guards.ts
|
|
566
610
|
function isRecord(value) {
|
|
567
611
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -1377,6 +1421,7 @@ var ERROR_CODES = [
|
|
|
1377
1421
|
"codex_session_create_timeout",
|
|
1378
1422
|
"codex_prompt_dispatch_timeout",
|
|
1379
1423
|
"codex_not_ready",
|
|
1424
|
+
"codex_transport_closed",
|
|
1380
1425
|
"codex_unrecoverable",
|
|
1381
1426
|
"unknown"
|
|
1382
1427
|
];
|
|
@@ -1410,6 +1455,7 @@ var ERROR_CODE_LABELS = {
|
|
|
1410
1455
|
codex_session_create_timeout: "Codex session creation timed out",
|
|
1411
1456
|
codex_prompt_dispatch_timeout: "Codex prompt dispatch timed out",
|
|
1412
1457
|
codex_not_ready: "Codex did not become ready",
|
|
1458
|
+
codex_transport_closed: "Codex transport closed",
|
|
1413
1459
|
codex_unrecoverable: "Codex unrecoverable failure",
|
|
1414
1460
|
unknown: "Unknown failure"
|
|
1415
1461
|
};
|
|
@@ -1521,6 +1567,12 @@ ${event.answer ? `**Answer:** ${event.answer}
|
|
|
1521
1567
|
function formatNumber(value) {
|
|
1522
1568
|
return value.toLocaleString();
|
|
1523
1569
|
}
|
|
1570
|
+
function latestCompletedPromptResult(prompts) {
|
|
1571
|
+
for (let i = prompts.length - 1; i >= 0; i--) {
|
|
1572
|
+
if (prompts[i].status === "completed") return prompts[i].result;
|
|
1573
|
+
}
|
|
1574
|
+
return null;
|
|
1575
|
+
}
|
|
1524
1576
|
function renderSessionTranscript(exportData) {
|
|
1525
1577
|
const lines = [];
|
|
1526
1578
|
const promptIds = exportData.prompts.map((prompt) => prompt.id);
|
|
@@ -1530,6 +1582,10 @@ function renderSessionTranscript(exportData) {
|
|
|
1530
1582
|
lines.push(`**Session:** ${exportData.session.id.slice(0, 8)} `);
|
|
1531
1583
|
lines.push(`**Created:** ${formatDate(exportData.session.createdAt)} `);
|
|
1532
1584
|
lines.push(`**Status:** ${exportData.session.status} `);
|
|
1585
|
+
const noChangeResult = latestCompletedPromptResult(exportData.prompts);
|
|
1586
|
+
if (!exportData.pr?.url && isNoChangesPromptResult(noChangeResult)) {
|
|
1587
|
+
lines.push(`**Outcome:** ${noChangeOutcomeCopy(noChangeResult.noChangeReason).title} `);
|
|
1588
|
+
}
|
|
1533
1589
|
lines.push(
|
|
1534
1590
|
`**Tokens:** ${formatNumber(exportData.tokens.inputTokens)} in / ${formatNumber(exportData.tokens.outputTokens)} out / ${formatNumber(exportData.tokens.totalTokens)} total`
|
|
1535
1591
|
);
|
|
@@ -1795,6 +1851,24 @@ function formatStatusLine(status) {
|
|
|
1795
1851
|
if (status.spawnDurationMs != null) details.push(`spawn ${(status.spawnDurationMs / 1e3).toFixed(1)}s`);
|
|
1796
1852
|
return details.length > 0 ? `[status] ${phaseLabel} | ${details.join(" | ")}` : `[status] ${phaseLabel}`;
|
|
1797
1853
|
}
|
|
1854
|
+
async function printNoChangeOutcome(config, sessionId) {
|
|
1855
|
+
try {
|
|
1856
|
+
const data = await apiFetch(
|
|
1857
|
+
config,
|
|
1858
|
+
`/api/sessions/${sessionId}/prompts`
|
|
1859
|
+
);
|
|
1860
|
+
const prompts = data.prompts ?? [];
|
|
1861
|
+
for (let i = prompts.length - 1; i >= 0; i--) {
|
|
1862
|
+
if (prompts[i].status !== "completed") continue;
|
|
1863
|
+
const result = prompts[i].result;
|
|
1864
|
+
if (isNoChangesPromptResult(result)) {
|
|
1865
|
+
console.log(`[outcome] ${noChangeOutcomeCopy(result.noChangeReason).title}`);
|
|
1866
|
+
}
|
|
1867
|
+
break;
|
|
1868
|
+
}
|
|
1869
|
+
} catch {
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1798
1872
|
async function fetchPromptLabels(config, sessionId) {
|
|
1799
1873
|
const data = await apiFetch(config, `/api/sessions/${sessionId}/prompts`);
|
|
1800
1874
|
return buildPromptLabelMap(data.prompts);
|
|
@@ -1873,7 +1947,16 @@ async function watchCommand(sessionId, options, command) {
|
|
|
1873
1947
|
console.log(rendered.line);
|
|
1874
1948
|
}
|
|
1875
1949
|
if (receivedFullPage) continue;
|
|
1876
|
-
if (parsed.status?.phase && isWatchTerminal(parsed.status.phase, parsed.status.sessionKind))
|
|
1950
|
+
if (parsed.status?.phase && isWatchTerminal(parsed.status.phase, parsed.status.sessionKind)) {
|
|
1951
|
+
if (!json && parsed.status.phase === "completed") {
|
|
1952
|
+
if (textOpen) {
|
|
1953
|
+
process.stdout.write("\n");
|
|
1954
|
+
textOpen = false;
|
|
1955
|
+
}
|
|
1956
|
+
await printNoChangeOutcome(config, sessionId);
|
|
1957
|
+
}
|
|
1958
|
+
break;
|
|
1959
|
+
}
|
|
1877
1960
|
await sleep(effectivePollIntervalMs);
|
|
1878
1961
|
}
|
|
1879
1962
|
} finally {
|
|
@@ -2106,7 +2189,6 @@ async function listSessionsCommand(options, command) {
|
|
|
2106
2189
|
if (options.status) query.set("status", options.status);
|
|
2107
2190
|
if (options.scope) query.set("scope", options.scope);
|
|
2108
2191
|
if (options.search) query.set("q", options.search);
|
|
2109
|
-
if (options.tag) query.set("tag", options.tag);
|
|
2110
2192
|
if (options.repo) query.set("repo", options.repo);
|
|
2111
2193
|
if (options.limit) query.set("limit", options.limit);
|
|
2112
2194
|
if (options.cursor) query.set("cursor", options.cursor);
|
|
@@ -2126,9 +2208,7 @@ async function listSessionsCommand(options, command) {
|
|
|
2126
2208
|
const id = String(session.id ?? session.sessionId ?? "");
|
|
2127
2209
|
const status = String(session.status ?? "");
|
|
2128
2210
|
const title = typeof session.title === "string" ? ` ${session.title}` : "";
|
|
2129
|
-
|
|
2130
|
-
const tagText = tags.length > 0 ? ` tags: ${tags.join(", ")}` : "";
|
|
2131
|
-
console.log(`${id} ${status}${title}${tagText}`);
|
|
2211
|
+
console.log(`${id} ${status}${title}`);
|
|
2132
2212
|
}
|
|
2133
2213
|
if (payload.nextCursor) console.log(`Next cursor: ${payload.nextCursor}`);
|
|
2134
2214
|
}
|
|
@@ -2525,21 +2605,21 @@ Examples:
|
|
|
2525
2605
|
arcanist sessions get <session-id> --json
|
|
2526
2606
|
`
|
|
2527
2607
|
).action((sessionId, options, command) => getSessionCommand(sessionId, options, command));
|
|
2528
|
-
sessions.command("list").description("List sessions").option("--status <status>", "Filter by session status").option("--scope <scope>", "Session scope: mine or business").option("--search <query>", "Search session titles
|
|
2608
|
+
sessions.command("list").description("List sessions").option("--status <status>", "Filter by session status").option("--scope <scope>", "Session scope: mine or business").option("--search <query>", "Search session titles and repo metadata").option("--repo <repo>", "Filter by repo metadata").option("--limit <n>", "Maximum sessions to return").option("--cursor <cursor>", "Pagination cursor").addHelpText(
|
|
2529
2609
|
"after",
|
|
2530
2610
|
`
|
|
2531
2611
|
Examples:
|
|
2532
2612
|
arcanist sessions list
|
|
2533
2613
|
arcanist sessions list --status idle --json
|
|
2534
|
-
arcanist sessions list --search "architect agent" --
|
|
2614
|
+
arcanist sessions list --search "architect agent" --repo owner/repo
|
|
2535
2615
|
`
|
|
2536
2616
|
).action((options, command) => listSessionsCommand(options, command));
|
|
2537
|
-
sessions.command("search").description("Search sessions by title
|
|
2617
|
+
sessions.command("search").description("Search sessions by title and repo metadata").argument("<query>", "Search query").option("--status <status>", "Filter by session status").option("--scope <scope>", "Session scope: mine or business").option("--repo <repo>", "Filter by repo metadata").option("--limit <n>", "Maximum sessions to return").option("--cursor <cursor>", "Pagination cursor").addHelpText(
|
|
2538
2618
|
"after",
|
|
2539
2619
|
`
|
|
2540
2620
|
Examples:
|
|
2541
2621
|
arcanist sessions search "architect agent"
|
|
2542
|
-
arcanist sessions search "mcp debugging" --
|
|
2622
|
+
arcanist sessions search "mcp debugging" --repo owner/repo --json
|
|
2543
2623
|
`
|
|
2544
2624
|
).action((query, options, command) => searchSessionsCommand(query, options, command));
|
|
2545
2625
|
sessions.command("events").description("Read or follow session replay events").argument("<session-id>", "Session ID").option("--after-sequence <n>", "Return events after this sequence").option("--after <n>", "Alias for --after-sequence").option("--before-sequence <n>", "Return events before this sequence").option("--before <n>", "Alias for --before-sequence").option("--prompt-id <id>", "Filter events by prompt ID").option("--limit <n>", "Maximum events to return").option("--follow", "Follow events until the session is idle").option("--poll-interval <ms>", "Polling interval in milliseconds", String(DEFAULT_WATCH_POLL_INTERVAL_MS)).addHelpText(
|