@tryarcanist/cli 0.1.84 → 0.1.86

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.
Files changed (2) hide show
  1. package/dist/index.js +82 -1
  2. 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);
@@ -1521,6 +1565,12 @@ ${event.answer ? `**Answer:** ${event.answer}
1521
1565
  function formatNumber(value) {
1522
1566
  return value.toLocaleString();
1523
1567
  }
1568
+ function latestCompletedPromptResult(prompts) {
1569
+ for (let i = prompts.length - 1; i >= 0; i--) {
1570
+ if (prompts[i].status === "completed") return prompts[i].result;
1571
+ }
1572
+ return null;
1573
+ }
1524
1574
  function renderSessionTranscript(exportData) {
1525
1575
  const lines = [];
1526
1576
  const promptIds = exportData.prompts.map((prompt) => prompt.id);
@@ -1530,6 +1580,10 @@ function renderSessionTranscript(exportData) {
1530
1580
  lines.push(`**Session:** ${exportData.session.id.slice(0, 8)} `);
1531
1581
  lines.push(`**Created:** ${formatDate(exportData.session.createdAt)} `);
1532
1582
  lines.push(`**Status:** ${exportData.session.status} `);
1583
+ const noChangeResult = latestCompletedPromptResult(exportData.prompts);
1584
+ if (!exportData.pr?.url && isNoChangesPromptResult(noChangeResult)) {
1585
+ lines.push(`**Outcome:** ${noChangeOutcomeCopy(noChangeResult.noChangeReason).title} `);
1586
+ }
1533
1587
  lines.push(
1534
1588
  `**Tokens:** ${formatNumber(exportData.tokens.inputTokens)} in / ${formatNumber(exportData.tokens.outputTokens)} out / ${formatNumber(exportData.tokens.totalTokens)} total`
1535
1589
  );
@@ -1795,6 +1849,24 @@ function formatStatusLine(status) {
1795
1849
  if (status.spawnDurationMs != null) details.push(`spawn ${(status.spawnDurationMs / 1e3).toFixed(1)}s`);
1796
1850
  return details.length > 0 ? `[status] ${phaseLabel} | ${details.join(" | ")}` : `[status] ${phaseLabel}`;
1797
1851
  }
1852
+ async function printNoChangeOutcome(config, sessionId) {
1853
+ try {
1854
+ const data = await apiFetch(
1855
+ config,
1856
+ `/api/sessions/${sessionId}/prompts`
1857
+ );
1858
+ const prompts = data.prompts ?? [];
1859
+ for (let i = prompts.length - 1; i >= 0; i--) {
1860
+ if (prompts[i].status !== "completed") continue;
1861
+ const result = prompts[i].result;
1862
+ if (isNoChangesPromptResult(result)) {
1863
+ console.log(`[outcome] ${noChangeOutcomeCopy(result.noChangeReason).title}`);
1864
+ }
1865
+ break;
1866
+ }
1867
+ } catch {
1868
+ }
1869
+ }
1798
1870
  async function fetchPromptLabels(config, sessionId) {
1799
1871
  const data = await apiFetch(config, `/api/sessions/${sessionId}/prompts`);
1800
1872
  return buildPromptLabelMap(data.prompts);
@@ -1873,7 +1945,16 @@ async function watchCommand(sessionId, options, command) {
1873
1945
  console.log(rendered.line);
1874
1946
  }
1875
1947
  if (receivedFullPage) continue;
1876
- if (parsed.status?.phase && isWatchTerminal(parsed.status.phase, parsed.status.sessionKind)) break;
1948
+ if (parsed.status?.phase && isWatchTerminal(parsed.status.phase, parsed.status.sessionKind)) {
1949
+ if (!json && parsed.status.phase === "completed") {
1950
+ if (textOpen) {
1951
+ process.stdout.write("\n");
1952
+ textOpen = false;
1953
+ }
1954
+ await printNoChangeOutcome(config, sessionId);
1955
+ }
1956
+ break;
1957
+ }
1877
1958
  await sleep(effectivePollIntervalMs);
1878
1959
  }
1879
1960
  } finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryarcanist/cli",
3
- "version": "0.1.84",
3
+ "version": "0.1.86",
4
4
  "description": "CLI for Arcanist — create and manage coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {