@tryarcanist/cli 0.1.132 → 0.1.133

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 (3) hide show
  1. package/README.md +15 -1
  2. package/dist/index.js +44 -16
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -131,7 +131,7 @@ arcanist sessions create your-org/your-repo "retry-safe create" --idempotency-ke
131
131
 
132
132
  `--backend` picks the agent runtime backend: `codex` (default) or `claude_code`. `--model` must be valid for the chosen backend — codex runs OpenAI models (`gpt-5.4` default, `gpt-5.5`), `claude_code` runs Anthropic models (`claude-opus-4-8` default, `claude-sonnet-4-6`) — and the CLI rejects a mismatch before any network call. `claude_code` sessions require an Anthropic API key configured in Settings.
133
133
 
134
- `--wait` blocks until the created prompt finishes and exits non-zero if the prompt finishes with `status: failed`, making it suitable for cron or other schedulers that alert on command failure. `--poll-interval <ms>` tunes the completion check frequency.
134
+ `--wait` blocks until the created prompt finishes, prints the resulting PR/branch line in human-readable mode when it is already available, and exits non-zero if the prompt finishes with `status: failed`, making it suitable for cron or other schedulers that alert on command failure. `--poll-interval <ms>` tunes the completion check frequency.
135
135
 
136
136
  Use `--base-branch <branch>` to target a non-default base branch. The CLI only validates that the branch value is non-empty; branch existence is checked later by the session runtime.
137
137
 
@@ -176,6 +176,8 @@ arcanist sessions get abc123
176
176
  arcanist sessions get abc123 --json
177
177
  ```
178
178
 
179
+ Human-readable output includes `PR: <url> (<branch>)` when the session has opened a PR, or `Branch: <branch>` when a produced branch is known but no PR URL is present yet. If publishing is still settling, rerun `sessions get`; JSON mode returns the raw session payload, with result fields at `.session.prUrl`, `.session.publishedBranch`, and `.session.lastBranch`.
180
+
179
181
  ### `arcanist sessions list`
180
182
 
181
183
  ```bash
@@ -324,6 +326,18 @@ arcanist sessions create your-org/your-repo "verify the new rate limiter is acti
324
326
 
325
327
  For cron, prefer `ARCANIST_TOKEN` or a logged-in `~/.arcanist/config.json` over passing `--token` on the command line.
326
328
 
329
+ To capture the PR URL after a successful run, use `create --wait` for the exit code, then read the session state:
330
+
331
+ ```bash
332
+ SESSION_ID=$(arcanist sessions create your-org/your-repo "fix the flaky test" --wait --json | jq -r .sessionId)
333
+ for _ in {1..20}; do
334
+ PR_URL=$(arcanist sessions get "$SESSION_ID" --json | jq -r '.session.prUrl // empty')
335
+ [ -n "$PR_URL" ] && break
336
+ sleep 5
337
+ done
338
+ [ -n "$PR_URL" ] || { echo "PR URL not ready for $SESSION_ID" >&2; exit 1; }
339
+ ```
340
+
327
341
  ## Troubleshooting
328
342
 
329
343
  - **401 on login verification**: token may be invalid or expired. Regenerate in **Settings > CLI Tokens**.
package/dist/index.js CHANGED
@@ -1023,22 +1023,6 @@ function noChangeOutcomeCopy(reason) {
1023
1023
  }
1024
1024
  }
1025
1025
 
1026
- // ../../shared/session/transient-disconnect.ts
1027
- var TRANSIENT_DISCONNECT_VISIBILITY_MS = 15e3;
1028
- function nextDisconnectMask(mask, previous, current, now) {
1029
- if (!current || current.sandboxSubstate !== "reconnecting") return null;
1030
- if (mask) return mask;
1031
- if (!previous || previous.sandboxSubstate === "reconnecting") return null;
1032
- return { since: now, heldPhase: previous.phase, heldSubstate: previous.sandboxSubstate ?? "none" };
1033
- }
1034
- function isDisconnectMaskActive(mask, now) {
1035
- return mask !== null && now - mask.since < TRANSIENT_DISCONNECT_VISIBILITY_MS;
1036
- }
1037
- function applyDisconnectMask(view, mask, now) {
1038
- if (!isDisconnectMaskActive(mask, now)) return view;
1039
- return { ...view, phase: mask.heldPhase, sandboxSubstate: mask.heldSubstate };
1040
- }
1041
-
1042
1026
  // ../../shared/transcript/malformed-search.ts
1043
1027
  var MALFORMED_SEARCH_BLOCKED_TRANSCRIPT_PREFIX = "Arcanist blocked this malformed search command before execution.";
1044
1028
  var BASH_UNMATCHED_QUOTE_EOF_RE = /\/bin\/bash:\s+-c:\s+line\s+\d+:\s+unexpected EOF while looking for matching [`'"][`'"]?/i;
@@ -2063,6 +2047,23 @@ ${event.answer ? `**Answer:** ${event.answer}
2063
2047
  function formatNumber(value) {
2064
2048
  return value.toLocaleString();
2065
2049
  }
2050
+ function stringField(value) {
2051
+ return typeof value === "string" && value.trim() ? value : null;
2052
+ }
2053
+ function formatSessionResult(session) {
2054
+ const prUrl = stringField(session.prUrl);
2055
+ const publishedBranch = stringField(session.publishedBranch);
2056
+ const lastBranch = stringField(session.lastBranch);
2057
+ const baseBranch = stringField(session.baseBranch);
2058
+ const branch = publishedBranch ?? (lastBranch && lastBranch !== baseBranch ? lastBranch : null);
2059
+ if (prUrl) {
2060
+ return `PR: ${prUrl}${branch ? ` (${branch})` : ""}`;
2061
+ }
2062
+ if (branch) {
2063
+ return `Branch: ${branch}`;
2064
+ }
2065
+ return null;
2066
+ }
2066
2067
  function latestCompletedPromptResult(prompts) {
2067
2068
  for (let i = prompts.length - 1; i >= 0; i--) {
2068
2069
  if (prompts[i].status === "completed") return prompts[i].result;
@@ -2314,6 +2315,22 @@ function renderWatchEvent(event, state) {
2314
2315
  }
2315
2316
  }
2316
2317
 
2318
+ // ../../shared/session/transient-disconnect.ts
2319
+ var TRANSIENT_DISCONNECT_VISIBILITY_MS = 15e3;
2320
+ function nextDisconnectMask(mask, previous, current, now) {
2321
+ if (!current || current.sandboxSubstate !== "reconnecting") return null;
2322
+ if (mask) return mask;
2323
+ if (!previous || previous.sandboxSubstate === "reconnecting") return null;
2324
+ return { since: now, heldPhase: previous.phase, heldSubstate: previous.sandboxSubstate ?? "none" };
2325
+ }
2326
+ function isDisconnectMaskActive(mask, now) {
2327
+ return mask !== null && now - mask.since < TRANSIENT_DISCONNECT_VISIBILITY_MS;
2328
+ }
2329
+ function applyDisconnectMask(view, mask, now) {
2330
+ if (!isDisconnectMaskActive(mask, now)) return view;
2331
+ return { ...view, phase: mask.heldPhase, sandboxSubstate: mask.heldSubstate };
2332
+ }
2333
+
2317
2334
  // src/commands/watch.ts
2318
2335
  function parsePollInterval(raw) {
2319
2336
  if (!raw) return DEFAULT_WATCH_POLL_INTERVAL_MS;
@@ -2621,6 +2638,15 @@ async function createCommand(repoUrl, promptArg, options, command) {
2621
2638
  if (sessionData.sessionUrl) console.log(`URL: ${sessionData.sessionUrl}`);
2622
2639
  }
2623
2640
  await waitForCreatedPrompt(sessionId, promptId, sessionData.sessionUrl, waitPollIntervalMs, runtime, command);
2641
+ if (!isJson(command, options)) {
2642
+ try {
2643
+ const sessionPayload = await apiFetch(config, `/api/sessions/${sessionId}`);
2644
+ const sessionState = sessionPayload.session && typeof sessionPayload.session === "object" ? sessionPayload.session : sessionPayload;
2645
+ const resultLine = formatSessionResult(sessionState);
2646
+ if (resultLine) console.log(resultLine);
2647
+ } catch {
2648
+ }
2649
+ }
2624
2650
  }
2625
2651
  if (isJson(command, options)) {
2626
2652
  const output = { sessionId };
@@ -3846,6 +3872,8 @@ async function getSessionCommand(sessionId, options, command) {
3846
3872
  console.log(`Status: ${String(session.phase ?? session.status ?? "unknown")}`);
3847
3873
  if (session.repoUrl) console.log(`Repo: ${String(session.repoUrl)}`);
3848
3874
  if (session.title) console.log(`Title: ${String(session.title)}`);
3875
+ const resultLine = formatSessionResult(session);
3876
+ if (resultLine) console.log(resultLine);
3849
3877
  }
3850
3878
  async function sessionEventsCommand(sessionId, options, command) {
3851
3879
  const afterSequence = resolveSequenceOption(options.afterSequence, options.after, "--after-sequence", "--after");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryarcanist/cli",
3
- "version": "0.1.132",
3
+ "version": "0.1.133",
4
4
  "description": "CLI for Arcanist — create and manage coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {