@tryarcanist/cli 0.1.214 → 0.1.216

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 +60 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -582,9 +582,10 @@ function assertArcanistSessionMutationAllowed(subcommand) {
582
582
  }
583
583
  );
584
584
  }
585
+ const commandName = subcommand === "review" ? "review" : `sessions ${subcommand}`;
585
586
  throw new CliError(
586
587
  "user",
587
- `\`arcanist sessions ${subcommand}\` is disabled inside ${role} sessions because nested Arcanist sessions are not observable to read-only agents.`,
588
+ `\`arcanist ${commandName}\` is disabled inside ${role} sessions because nested Arcanist work is not observable to read-only agents.`,
588
589
  {
589
590
  hint: "Use direct local/sandbox evidence instead, or report a verification gap rather than spawning another Arcanist session."
590
591
  }
@@ -4674,6 +4675,54 @@ function parseRespondConflict(err) {
4674
4675
  }
4675
4676
  }
4676
4677
 
4678
+ // src/commands/review.ts
4679
+ var PR_REVIEW_POLL_INTERVAL_MS = 1e4;
4680
+ var PR_REVIEW_WAIT_TIMEOUT_MS = 30 * 60 * 1e3;
4681
+ async function reviewCommand(prUrl, options = {}, command) {
4682
+ assertArcanistSessionMutationAllowed("review");
4683
+ const { config } = resolveBusinessContext(command, options);
4684
+ const trigger = await apiFetch(config, "/api/pr-reviews", {
4685
+ method: "POST",
4686
+ body: JSON.stringify({ prUrl, ...options.focus ? { focus: options.focus } : {} })
4687
+ });
4688
+ if (!options.wait || trigger.cached) {
4689
+ emit(command, options, trigger, (payload) => {
4690
+ if (payload.cached) console.log(`Zeus review already completed: ${payload.verdict ?? "unknown"}.`);
4691
+ else console.log(`Started Zeus review${payload.sessionId ? ` (${payload.sessionId})` : ""}.`);
4692
+ });
4693
+ return;
4694
+ }
4695
+ const result = await waitForReview(config, prUrl, trigger.sessionId ?? null);
4696
+ emit(command, options, result, (payload) => {
4697
+ console.log(`Zeus review: ${sanitizeTerminalText(payload.verdict)}. ${payload.findings.length} finding(s).`);
4698
+ for (const finding of payload.findings) {
4699
+ console.log(
4700
+ `${sanitizeTerminalText(finding.severity)} ${sanitizeTerminalText(finding.file)}:${finding.line} - ${sanitizeTerminalText(finding.title)}`
4701
+ );
4702
+ }
4703
+ });
4704
+ }
4705
+ function sanitizeTerminalText(value) {
4706
+ return value.replace(/\u001b\][^\u0007]*(?:\u0007|\u001b\\)/g, "").replace(/\u001b\[[0-?]*[ -/]*[@-~]/g, "").replace(/[\u0000-\u001f\u007f]/g, "");
4707
+ }
4708
+ async function waitForReview(config, prUrl, sessionId) {
4709
+ const deadline = Date.now() + PR_REVIEW_WAIT_TIMEOUT_MS;
4710
+ while (Date.now() < deadline) {
4711
+ const status = await apiFetch(
4712
+ config,
4713
+ `/api/pr-reviews/status?prUrl=${encodeURIComponent(prUrl)}`
4714
+ );
4715
+ if (status.status === "completed") {
4716
+ if (sessionId && status.sessionId !== sessionId) {
4717
+ throw new CliError("conflict", "PR review completed for a different attempt; retry the command.");
4718
+ }
4719
+ return { ...status, sessionId: status.sessionId ?? sessionId };
4720
+ }
4721
+ await new Promise((resolve2) => setTimeout(resolve2, PR_REVIEW_POLL_INTERVAL_MS));
4722
+ }
4723
+ throw new CliError("server", "Timed out waiting for Zeus review results.");
4724
+ }
4725
+
4677
4726
  // src/commands/sandbox.ts
4678
4727
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
4679
4728
  import { dirname as dirname2 } from "path";
@@ -6308,6 +6357,16 @@ cursor.command("use <state>").description("Turn using your saved Cursor subscrip
6308
6357
  cursor.command("status").description("Show whether your workspace is eligible and whether a Cursor subscription auth is saved").action((options, command) => agentSubscriptionStatusCommand(CURSOR_SUBSCRIPTION_CLI_CONFIG, options, command));
6309
6358
  cursor.command("logout").description("Deactivate the selector and remove the stored Cursor subscription auth for your user").action((options, command) => agentSubscriptionLogoutCommand(CURSOR_SUBSCRIPTION_CLI_CONFIG, options, command));
6310
6359
  var sessions = program.command("sessions").description("Session commands");
6360
+ program.command("review <pr-url>").description("Run a Zeus review for a GitHub pull request").option("--focus <text>", "Focus the review on a specific concern").option("--wait", "Wait for the review and print its verdict and findings").addHelpText(
6361
+ "after",
6362
+ `
6363
+ Examples:
6364
+ arcanist review https://github.com/org/repo/pull/123 --wait --json
6365
+ arcanist review https://github.com/org/repo/pull/123 --focus "Check auth" --wait
6366
+
6367
+ Zeus review is currently available to Arcanist members only.
6368
+ `
6369
+ ).action((prUrl, options, command) => reviewCommand(prUrl, options, command));
6311
6370
  addCreateOptions(sessions.command("create").description("Create a session and send a prompt")).action(
6312
6371
  (repoUrl, prompt, options, command) => createCommand(repoUrl, prompt, options, command)
6313
6372
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryarcanist/cli",
3
- "version": "0.1.214",
3
+ "version": "0.1.216",
4
4
  "description": "CLI for Arcanist — create and manage coding agent sessions",
5
5
  "type": "module",
6
6
  "bin": {