@tryarcanist/cli 0.1.224 → 0.1.226
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/README.md +3 -30
- package/dist/index.js +118 -155
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -194,11 +194,10 @@ arcanist sessions create your-org/your-repo "refactor auth" --reasoning-effort x
|
|
|
194
194
|
arcanist sessions create your-org/your-repo "verify this automatically" --auto-verify
|
|
195
195
|
arcanist sessions create your-org/your-repo "fix release branch" --base-branch release/2026-06
|
|
196
196
|
arcanist sessions create your-org/your-repo "review the trace" --uploaded-file trace.txt
|
|
197
|
-
arcanist sessions create your-org/your-repo "verify the deployed change" --cold
|
|
198
197
|
arcanist sessions create your-org/your-repo "retry-safe create" --idempotency-key 1f0e6f1a-...
|
|
199
198
|
```
|
|
200
199
|
|
|
201
|
-
`--backend` picks the agent runtime backend: `codex` (default) or `
|
|
200
|
+
`--backend` picks the agent runtime backend: `codex` (default), `claude_code`, `opencode`, `cursor`, or `grok`. `--model` must be valid for the chosen backend and the CLI rejects a mismatch before any network call; run `arcanist models list` for the selectable models per backend. When `--model` is omitted the backend default is used. Non-codex backends require the matching provider credential configured in Settings.
|
|
202
201
|
|
|
203
202
|
`--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. JSON mode waits quietly and prints the create payload after the prompt completes successfully. `--poll-interval <ms>` tunes the completion check frequency.
|
|
204
203
|
|
|
@@ -217,7 +216,7 @@ The CLI echoes the request value as `jiraIssue` in JSON output; pickup writeback
|
|
|
217
216
|
|
|
218
217
|
Repeatable `--uploaded-file <path>` flags attach local UTF-8 text files to the prompt. Uploaded file names come from the local basename; directory components are not sent.
|
|
219
218
|
|
|
220
|
-
|
|
219
|
+
Sessions always start from a fresh sandbox (the warm sandbox pool was removed).
|
|
221
220
|
|
|
222
221
|
`--idempotency-key <uuid>` is for manually retrying a create request that may have reached the server.
|
|
223
222
|
The CLI derives separate session and prompt idempotency keys from the provided value.
|
|
@@ -243,7 +242,7 @@ The PR URL must be `https://github.com/<owner>/<repo>/pull/<number>`.
|
|
|
243
242
|
The CLI derives the repo from that URL, creates a QA session with `qa: true` and `targetPrUrl`, then enqueues the verifier prompt (skipped when the server signals `promptAlreadyEnqueued`).
|
|
244
243
|
Inspect progress with the session URL or the session events stream.
|
|
245
244
|
|
|
246
|
-
`--backend` picks the agent runtime backend: `codex` (default), `claude_code`, or `
|
|
245
|
+
`--backend` picks the agent runtime backend: `codex` (default), `claude_code`, `opencode`, `cursor`, or `grok`.
|
|
247
246
|
`--model` must be valid for the chosen backend, and the CLI rejects mismatches before any network call.
|
|
248
247
|
When `--model` is omitted, the backend default is used.
|
|
249
248
|
|
|
@@ -322,17 +321,6 @@ JSON mode returns `{sessions, nextCursor}`.
|
|
|
322
321
|
`--all` follows cursors until completion and returns `nextCursor: null`.
|
|
323
322
|
Search is metadata-only: generated titles and repo metadata.
|
|
324
323
|
|
|
325
|
-
### `arcanist sessions search <query>`
|
|
326
|
-
|
|
327
|
-
```bash
|
|
328
|
-
arcanist sessions search "architect agent"
|
|
329
|
-
arcanist sessions search "mcp debugging" --repo your-org/your-repo --json
|
|
330
|
-
arcanist sessions search "repo access" --status idle --scope business --limit 20 --cursor <cursor>
|
|
331
|
-
arcanist sessions search "repo access" --all --json
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
Uses the same metadata-only index and filters as `sessions list`: `--status`, `--scope`, `--repo`, `--limit`, `--cursor`, and `--all`.
|
|
335
|
-
|
|
336
324
|
### `arcanist sessions events <session-id>`
|
|
337
325
|
|
|
338
326
|
Reads canonical session replay events. Cursors are sequence-based.
|
|
@@ -367,15 +355,6 @@ arcanist sessions transcript abc123 --last 20
|
|
|
367
355
|
|
|
368
356
|
`--last <n>` renders only the last `n` stored transcript events after fetching the session export.
|
|
369
357
|
|
|
370
|
-
### `arcanist sessions watch <session-id>`
|
|
371
|
-
|
|
372
|
-
Watches session activity until the session becomes idle. For machine-readable streaming, prefer `arcanist sessions events --follow --json`.
|
|
373
|
-
|
|
374
|
-
```bash
|
|
375
|
-
arcanist sessions watch abc123
|
|
376
|
-
arcanist sessions watch abc123 --poll-interval 500
|
|
377
|
-
```
|
|
378
|
-
|
|
379
358
|
### `arcanist sessions usage <session-id>`
|
|
380
359
|
|
|
381
360
|
```bash
|
|
@@ -510,12 +489,6 @@ SESSION_ID=$(arcanist sessions create your-org/your-repo "audit dependency licen
|
|
|
510
489
|
arcanist sessions events "$SESSION_ID" --follow --json | jq -r 'select(.type == "assistant_message")'
|
|
511
490
|
```
|
|
512
491
|
|
|
513
|
-
Verify a freshly deployed change with a guaranteed-fresh sandbox:
|
|
514
|
-
|
|
515
|
-
```bash
|
|
516
|
-
arcanist sessions create your-org/your-repo "verify the new rate limiter is active" --cold --wait
|
|
517
|
-
```
|
|
518
|
-
|
|
519
492
|
For cron, prefer `ARCANIST_TOKEN` or a logged-in `~/.arcanist/config.json` over passing `--token` on the command line.
|
|
520
493
|
|
|
521
494
|
To capture the PR URL after a successful run, read the best-effort result fields from `create --wait --json`:
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,31 @@
|
|
|
4
4
|
import { createRequire as createRequire2 } from "module";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
|
|
7
|
+
// ../../shared/agent/agent-runtime-backend.ts
|
|
8
|
+
var CODEX_AGENT_RUNTIME_BACKEND = "codex";
|
|
9
|
+
var CLAUDE_CODE_AGENT_RUNTIME_BACKEND = "claude_code";
|
|
10
|
+
var OPENCODE_AGENT_RUNTIME_BACKEND = "opencode";
|
|
11
|
+
var CURSOR_AGENT_RUNTIME_BACKEND = "cursor";
|
|
12
|
+
var GROK_AGENT_RUNTIME_BACKEND = "grok";
|
|
13
|
+
var AGENT_RUNTIME_BACKENDS = [
|
|
14
|
+
CODEX_AGENT_RUNTIME_BACKEND,
|
|
15
|
+
CLAUDE_CODE_AGENT_RUNTIME_BACKEND,
|
|
16
|
+
OPENCODE_AGENT_RUNTIME_BACKEND,
|
|
17
|
+
CURSOR_AGENT_RUNTIME_BACKEND,
|
|
18
|
+
GROK_AGENT_RUNTIME_BACKEND
|
|
19
|
+
];
|
|
20
|
+
var AGENT_RUNTIME_BACKEND_NAMES = {
|
|
21
|
+
[CODEX_AGENT_RUNTIME_BACKEND]: "Codex",
|
|
22
|
+
[CLAUDE_CODE_AGENT_RUNTIME_BACKEND]: "Claude Code",
|
|
23
|
+
// "opencode" is intentionally lowercase to match the project's brand name.
|
|
24
|
+
[OPENCODE_AGENT_RUNTIME_BACKEND]: "opencode",
|
|
25
|
+
[CURSOR_AGENT_RUNTIME_BACKEND]: "Cursor",
|
|
26
|
+
[GROK_AGENT_RUNTIME_BACKEND]: "Grok Build"
|
|
27
|
+
};
|
|
28
|
+
function isAgentRuntimeBackend(value) {
|
|
29
|
+
return AGENT_RUNTIME_BACKENDS.includes(value);
|
|
30
|
+
}
|
|
31
|
+
|
|
7
32
|
// src/commands/agent-subscription.ts
|
|
8
33
|
import { execFileSync, spawn as spawn2 } from "child_process";
|
|
9
34
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -1138,29 +1163,61 @@ async function whoamiCommand(options, command) {
|
|
|
1138
1163
|
});
|
|
1139
1164
|
}
|
|
1140
1165
|
|
|
1141
|
-
//
|
|
1142
|
-
var
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
function
|
|
1163
|
-
|
|
1166
|
+
// src/utils/pagination.ts
|
|
1167
|
+
var MAX_ALL_PAGES = 1e3;
|
|
1168
|
+
async function fetchPages(label, all, initialCursor, fetchPage) {
|
|
1169
|
+
const items = [];
|
|
1170
|
+
let cursor2 = initialCursor;
|
|
1171
|
+
let nextCursor = null;
|
|
1172
|
+
let pageCount = 0;
|
|
1173
|
+
do {
|
|
1174
|
+
pageCount += 1;
|
|
1175
|
+
if (all && pageCount > MAX_ALL_PAGES) {
|
|
1176
|
+
throw new CliError("user", `${label} exceeded ${MAX_ALL_PAGES} pages without reaching the end.`);
|
|
1177
|
+
}
|
|
1178
|
+
const page = await fetchPage(cursor2);
|
|
1179
|
+
items.push(...page.items);
|
|
1180
|
+
nextCursor = page.nextCursor;
|
|
1181
|
+
cursor2 = nextCursor ?? void 0;
|
|
1182
|
+
} while (all && nextCursor);
|
|
1183
|
+
return { items, nextCursor: all ? null : nextCursor };
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// ../../shared/github/repo-url.ts
|
|
1187
|
+
function parseGithubRepoFullName(value) {
|
|
1188
|
+
const shorthand = value.match(/^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/);
|
|
1189
|
+
if (shorthand) return { owner: shorthand[1], repo: shorthand[2] };
|
|
1190
|
+
const ssh = value.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
1191
|
+
if (ssh) return { owner: ssh[1], repo: ssh[2] };
|
|
1192
|
+
const https = value.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
1193
|
+
if (https) return { owner: https[1], repo: https[2] };
|
|
1194
|
+
return null;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// src/git.ts
|
|
1198
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
1199
|
+
function git(args) {
|
|
1200
|
+
try {
|
|
1201
|
+
return execFileSync2("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
1202
|
+
} catch (err) {
|
|
1203
|
+
throw new CliError("user", `git ${args.join(" ")} failed: ${stringifyError(err)}`);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
function currentRepo() {
|
|
1207
|
+
const parsed = parseGithubRepoFullName(git(["remote", "get-url", "origin"]));
|
|
1208
|
+
if (!parsed) throw new CliError("user", "origin remote must point at a GitHub repository");
|
|
1209
|
+
return { owner: parsed.owner, repo: parsed.repo };
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
// src/utils/repo-arg.ts
|
|
1213
|
+
function parseRepoArg(value, argName = "repo") {
|
|
1214
|
+
const parsed = parseGithubRepoFullName(value);
|
|
1215
|
+
if (!parsed) throw new CliError("user", `${argName} must be owner/name or a GitHub URL`);
|
|
1216
|
+
return { owner: parsed.owner, repo: parsed.repo.replace(/\.git$/, "") };
|
|
1217
|
+
}
|
|
1218
|
+
function parseRepoArgOrCurrent(value, argName = "repo") {
|
|
1219
|
+
if (value === void 0) return currentRepo();
|
|
1220
|
+
return parseRepoArg(value, argName);
|
|
1164
1221
|
}
|
|
1165
1222
|
|
|
1166
1223
|
// ../../shared/utils/type-guards.ts
|
|
@@ -1909,61 +1966,40 @@ var SESSION_START_MODEL_PROVIDER_GROUPS_BY_SUBSCRIPTIONS = {
|
|
|
1909
1966
|
"true:true": buildSubscriptionAwareGroups({ codexSubscription: true, grokSubscription: true })
|
|
1910
1967
|
};
|
|
1911
1968
|
|
|
1912
|
-
// src/
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
pageCount += 1;
|
|
1921
|
-
if (all && pageCount > MAX_ALL_PAGES) {
|
|
1922
|
-
throw new CliError("user", `${label} exceeded ${MAX_ALL_PAGES} pages without reaching the end.`);
|
|
1923
|
-
}
|
|
1924
|
-
const page = await fetchPage(cursor2);
|
|
1925
|
-
items.push(...page.items);
|
|
1926
|
-
nextCursor = page.nextCursor;
|
|
1927
|
-
cursor2 = nextCursor ?? void 0;
|
|
1928
|
-
} while (all && nextCursor);
|
|
1929
|
-
return { items, nextCursor: all ? null : nextCursor };
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
// ../../shared/github/repo-url.ts
|
|
1933
|
-
function parseGithubRepoFullName(value) {
|
|
1934
|
-
const shorthand = value.match(/^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/);
|
|
1935
|
-
if (shorthand) return { owner: shorthand[1], repo: shorthand[2] };
|
|
1936
|
-
const ssh = value.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
1937
|
-
if (ssh) return { owner: ssh[1], repo: ssh[2] };
|
|
1938
|
-
const https = value.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
1939
|
-
if (https) return { owner: https[1], repo: https[2] };
|
|
1940
|
-
return null;
|
|
1969
|
+
// src/commands/model-options.ts
|
|
1970
|
+
function backendForProviderPrefix(rawModel) {
|
|
1971
|
+
const provider = rawModel.match(/^([a-z]+)[/:]/i)?.[1]?.toLowerCase();
|
|
1972
|
+
if (provider === "anthropic") return CLAUDE_CODE_AGENT_RUNTIME_BACKEND;
|
|
1973
|
+
if (provider === "baseten" || provider === "xai") return OPENCODE_AGENT_RUNTIME_BACKEND;
|
|
1974
|
+
if (provider === "cursor") return CURSOR_AGENT_RUNTIME_BACKEND;
|
|
1975
|
+
if (provider === "grok") return GROK_AGENT_RUNTIME_BACKEND;
|
|
1976
|
+
return void 0;
|
|
1941
1977
|
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1978
|
+
function resolveModelAndBackend(options) {
|
|
1979
|
+
let agentRuntimeBackend = CODEX_AGENT_RUNTIME_BACKEND;
|
|
1980
|
+
const normalizedModel = options.model !== void 0 ? extractModelId(options.model) : void 0;
|
|
1981
|
+
if (options.backend !== void 0) {
|
|
1982
|
+
if (!isAgentRuntimeBackend(options.backend)) {
|
|
1983
|
+
throw new CliError(
|
|
1984
|
+
"user",
|
|
1985
|
+
`Invalid --backend '${options.backend}'. Expected ${AGENT_RUNTIME_BACKENDS.join(", ")}.`
|
|
1986
|
+
);
|
|
1987
|
+
}
|
|
1988
|
+
agentRuntimeBackend = options.backend;
|
|
1989
|
+
} else if (options.model !== void 0) {
|
|
1990
|
+
const derived = (normalizedModel ? getAgentRuntimeBackendForModel(normalizedModel) : void 0) ?? backendForProviderPrefix(options.model);
|
|
1991
|
+
if (derived) agentRuntimeBackend = derived;
|
|
1950
1992
|
}
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
if (!parsed) throw new CliError("user", `${argName} must be owner/name or a GitHub URL`);
|
|
1962
|
-
return { owner: parsed.owner, repo: parsed.repo.replace(/\.git$/, "") };
|
|
1963
|
-
}
|
|
1964
|
-
function parseRepoArgOrCurrent(value, argName = "repo") {
|
|
1965
|
-
if (value === void 0) return currentRepo();
|
|
1966
|
-
return parseRepoArg(value, argName);
|
|
1993
|
+
if (options.model !== void 0) {
|
|
1994
|
+
if (normalizedModel === void 0 || !isSessionStartModelAllowedForBackend(normalizedModel, agentRuntimeBackend)) {
|
|
1995
|
+
const allowed = getSessionStartModelIdsForBackend(agentRuntimeBackend).join(", ");
|
|
1996
|
+
throw new CliError(
|
|
1997
|
+
"user",
|
|
1998
|
+
`Model '${options.model}' is not selectable for backend '${agentRuntimeBackend}'. Allowed: ${allowed}.`
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
return { agentRuntimeBackend, modelId: normalizedModel };
|
|
1967
2003
|
}
|
|
1968
2004
|
|
|
1969
2005
|
// src/commands/automations.ts
|
|
@@ -1996,15 +2032,7 @@ async function createAutomationCommand(repoUrl, promptArg, options, command) {
|
|
|
1996
2032
|
}
|
|
1997
2033
|
const runtime = getRuntimeOptions(command, options);
|
|
1998
2034
|
const config = requireConfig(runtime);
|
|
1999
|
-
|
|
2000
|
-
if (options.model !== void 0) {
|
|
2001
|
-
normalizedModel = extractModelId(options.model);
|
|
2002
|
-
const backend = resolveAutomationModelBackend(options.model, normalizedModel);
|
|
2003
|
-
if (normalizedModel === void 0 || !isSessionStartModelAllowedForBackend(normalizedModel, backend)) {
|
|
2004
|
-
const allowed = getSessionStartModelIdsForBackend(backend).join(", ");
|
|
2005
|
-
throw new CliError("user", `Model '${options.model}' is not selectable. Allowed: ${allowed}.`);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2035
|
+
const { modelId: normalizedModel } = resolveModelAndBackend(options);
|
|
2008
2036
|
const body = {
|
|
2009
2037
|
repoOwner: repo.owner,
|
|
2010
2038
|
repoName: repo.repo,
|
|
@@ -2077,18 +2105,6 @@ async function deleteAutomationCommand(id, options, command) {
|
|
|
2077
2105
|
}
|
|
2078
2106
|
console.log(`Deleted automation ${id}.`);
|
|
2079
2107
|
}
|
|
2080
|
-
function resolveAutomationModelBackend(rawModel, normalizedModel) {
|
|
2081
|
-
if (normalizedModel) {
|
|
2082
|
-
const backend = getAgentRuntimeBackendForModel(normalizedModel);
|
|
2083
|
-
if (backend) return backend;
|
|
2084
|
-
}
|
|
2085
|
-
const provider = rawModel.match(/^([a-z]+)[/:]/i)?.[1]?.toLowerCase();
|
|
2086
|
-
if (provider === "anthropic") return CLAUDE_CODE_AGENT_RUNTIME_BACKEND;
|
|
2087
|
-
if (provider === "baseten" || provider === "xai") return OPENCODE_AGENT_RUNTIME_BACKEND;
|
|
2088
|
-
if (provider === "cursor") return CURSOR_AGENT_RUNTIME_BACKEND;
|
|
2089
|
-
if (provider === "grok") return GROK_AGENT_RUNTIME_BACKEND;
|
|
2090
|
-
return CODEX_AGENT_RUNTIME_BACKEND;
|
|
2091
|
-
}
|
|
2092
2108
|
async function automationApiFetch(config, path, init) {
|
|
2093
2109
|
try {
|
|
2094
2110
|
return await apiFetch(config, path, init);
|
|
@@ -3842,35 +3858,6 @@ function unwrapSessionState(payload) {
|
|
|
3842
3858
|
return payload.session && typeof payload.session === "object" ? payload.session : payload;
|
|
3843
3859
|
}
|
|
3844
3860
|
|
|
3845
|
-
// src/commands/model-options.ts
|
|
3846
|
-
function resolveModelAndBackend(options) {
|
|
3847
|
-
let agentRuntimeBackend = CODEX_AGENT_RUNTIME_BACKEND;
|
|
3848
|
-
if (options.backend !== void 0) {
|
|
3849
|
-
if (!isAgentRuntimeBackend(options.backend)) {
|
|
3850
|
-
throw new CliError(
|
|
3851
|
-
"user",
|
|
3852
|
-
`Invalid --backend '${options.backend}'. Expected ${AGENT_RUNTIME_BACKENDS.join(", ")}.`
|
|
3853
|
-
);
|
|
3854
|
-
}
|
|
3855
|
-
agentRuntimeBackend = options.backend;
|
|
3856
|
-
} else if (options.model !== void 0) {
|
|
3857
|
-
const normalizedModel = extractModelId(options.model);
|
|
3858
|
-
const derived = normalizedModel ? getAgentRuntimeBackendForModel(normalizedModel) : void 0;
|
|
3859
|
-
if (derived) agentRuntimeBackend = derived;
|
|
3860
|
-
}
|
|
3861
|
-
if (options.model !== void 0) {
|
|
3862
|
-
const normalizedModel = extractModelId(options.model);
|
|
3863
|
-
if (normalizedModel === void 0 || !isSessionStartModelAllowedForBackend(normalizedModel, agentRuntimeBackend)) {
|
|
3864
|
-
const allowed = getSessionStartModelIdsForBackend(agentRuntimeBackend).join(", ");
|
|
3865
|
-
throw new CliError(
|
|
3866
|
-
"user",
|
|
3867
|
-
`Model '${options.model}' is not selectable for backend '${agentRuntimeBackend}'. Allowed: ${allowed}.`
|
|
3868
|
-
);
|
|
3869
|
-
}
|
|
3870
|
-
}
|
|
3871
|
-
return agentRuntimeBackend;
|
|
3872
|
-
}
|
|
3873
|
-
|
|
3874
3861
|
// ../../shared/session/transient-disconnect.ts
|
|
3875
3862
|
var TRANSIENT_DISCONNECT_VISIBILITY_MS = 15e3;
|
|
3876
3863
|
function nextDisconnectMask(mask, previous, current, now) {
|
|
@@ -4137,7 +4124,7 @@ async function createCommand(repoUrl, promptArg, options, command) {
|
|
|
4137
4124
|
const runtime = getRuntimeOptions(command, options);
|
|
4138
4125
|
assertArcanistSessionMutationAllowed("create");
|
|
4139
4126
|
const config = requireConfig(runtime);
|
|
4140
|
-
const agentRuntimeBackend = resolveModelAndBackend(options);
|
|
4127
|
+
const { agentRuntimeBackend } = resolveModelAndBackend(options);
|
|
4141
4128
|
const prompt = options.onboarding ? ONBOARDING_PROMPT : await resolvePromptInput(promptArg, options);
|
|
4142
4129
|
const waitPollIntervalMs = options.wait ? parsePollInterval(options.pollInterval) : null;
|
|
4143
4130
|
const repoError = validateRepoUrl(repoUrl);
|
|
@@ -4185,7 +4172,6 @@ async function createCommand(repoUrl, promptArg, options, command) {
|
|
|
4185
4172
|
if (jiraIssue) body.jiraIssue = jiraIssue;
|
|
4186
4173
|
if (continuePr) body.continuePrUrl = continuePr;
|
|
4187
4174
|
if (continueMode) body.continueMode = continueMode;
|
|
4188
|
-
if (options.cold) body.cold = true;
|
|
4189
4175
|
if (options.onboarding) body.onboarding = true;
|
|
4190
4176
|
const sessionData = await apiFetch(config, "/api/sessions", {
|
|
4191
4177
|
method: "POST",
|
|
@@ -4564,7 +4550,7 @@ async function qaCommand(prUrl, options, command) {
|
|
|
4564
4550
|
assertArcanistSessionMutationAllowed("qa");
|
|
4565
4551
|
const config = requireConfig(runtime);
|
|
4566
4552
|
const { targetPrUrl, repoUrl } = parseCanonicalPrUrl(prUrl);
|
|
4567
|
-
const agentRuntimeBackend = resolveModelAndBackend(options);
|
|
4553
|
+
const { agentRuntimeBackend } = resolveModelAndBackend(options);
|
|
4568
4554
|
const idempotencyKey = options.idempotencyKey ?? randomIdempotencyKey();
|
|
4569
4555
|
const sessionIdempotencyKey = `${idempotencyKey}:session`;
|
|
4570
4556
|
const promptIdempotencyKey = `${idempotencyKey}:prompt`;
|
|
@@ -5884,9 +5870,6 @@ async function listSessionsCommand(options, command) {
|
|
|
5884
5870
|
}
|
|
5885
5871
|
if (payload.nextCursor) console.log(`Next cursor: ${payload.nextCursor}`);
|
|
5886
5872
|
}
|
|
5887
|
-
async function searchSessionsCommand(query, options, command) {
|
|
5888
|
-
await listSessionsCommand({ ...options, search: query }, command);
|
|
5889
|
-
}
|
|
5890
5873
|
async function getSessionCommand(sessionId, options, command) {
|
|
5891
5874
|
const runtime = getRuntimeOptions(command, options);
|
|
5892
5875
|
const config = requireConfig(runtime);
|
|
@@ -6230,7 +6213,7 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
|
6230
6213
|
applyColorEnvironment(getRuntimeOptions(actionCommand));
|
|
6231
6214
|
});
|
|
6232
6215
|
function addCreateOptions(cmd) {
|
|
6233
|
-
return cmd.argument("<repo-url>", "Repository URL").argument("[prompt]", "Prompt to send, or '-' to read stdin").option("--model <model>", "Model to use").option("--backend <backend>",
|
|
6216
|
+
return cmd.argument("<repo-url>", "Repository URL").argument("[prompt]", "Prompt to send, or '-' to read stdin").option("--model <model>", "Model to use").option("--backend <backend>", `Agent runtime backend: ${AGENT_RUNTIME_BACKENDS.join(", ")} (default codex)`).option("--reasoning-effort <effort>", "Reasoning effort to use for models that support it").option("--auto-verify", "Opt this session into automatic QA verification after PR creation").option("--base-branch <branch>", "Base branch to create the session against (defaults to the repo default branch)").option(
|
|
6234
6217
|
"--start-branch <branch>",
|
|
6235
6218
|
"Resume an existing branch with its history instead of forking a new one off base"
|
|
6236
6219
|
).option("--linear-issue <id|url>", "Associate the session with a Linear issue for pickup writeback").option("--jira-issue <key|url>", "Associate the session with a Jira issue for pickup writeback").option("--continue-pr <url>", "Continue from an existing same-repo pull request").option("--continue-mode <mode>", "Continuation mode: auto (default), update-pr, or new-pr").option("--prompt-stdin", "Read prompt from stdin").option(
|
|
@@ -6241,7 +6224,7 @@ function addCreateOptions(cmd) {
|
|
|
6241
6224
|
"--poll-interval <ms>",
|
|
6242
6225
|
"Polling interval in milliseconds while waiting",
|
|
6243
6226
|
String(DEFAULT_WATCH_POLL_INTERVAL_MS)
|
|
6244
|
-
).option("--idempotency-key <uuid>", "Request idempotency key for safe manual retries").option("--
|
|
6227
|
+
).option("--idempotency-key <uuid>", "Request idempotency key for safe manual retries").option("--onboarding", "Create an onboarding session that authors the repo's Arcanist configuration").addHelpText(
|
|
6245
6228
|
"after",
|
|
6246
6229
|
`
|
|
6247
6230
|
Examples:
|
|
@@ -6280,7 +6263,7 @@ JSON mode returns {sessionId, promptId?}
|
|
|
6280
6263
|
);
|
|
6281
6264
|
}
|
|
6282
6265
|
function addQaOptions(cmd) {
|
|
6283
|
-
return cmd.argument("<pr-url>", "GitHub pull request URL to QA").option("--model <model>", "Model to use").option("--backend <backend>",
|
|
6266
|
+
return cmd.argument("<pr-url>", "GitHub pull request URL to QA").option("--model <model>", "Model to use").option("--backend <backend>", `Agent runtime backend: ${AGENT_RUNTIME_BACKENDS.join(", ")} (default codex)`).option("--reasoning-effort <effort>", "Reasoning effort to use for models that support it").option("--wait", "Wait for the QA prompt to finish and exit non-zero if it fails").option(
|
|
6284
6267
|
"--poll-interval <ms>",
|
|
6285
6268
|
"Polling interval in milliseconds while waiting",
|
|
6286
6269
|
String(DEFAULT_WATCH_POLL_INTERVAL_MS)
|
|
@@ -6468,18 +6451,6 @@ JSON:
|
|
|
6468
6451
|
JSON mode returns {sessions, nextCursor}. --all follows cursors until nextCursor is null.
|
|
6469
6452
|
`
|
|
6470
6453
|
).action((options, command) => listSessionsCommand(options, command));
|
|
6471
|
-
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").option("--all", "Fetch all pages").addHelpText(
|
|
6472
|
-
"after",
|
|
6473
|
-
`
|
|
6474
|
-
Examples:
|
|
6475
|
-
arcanist sessions search "architect agent"
|
|
6476
|
-
arcanist sessions search "mcp debugging" --repo owner/repo --json
|
|
6477
|
-
arcanist sessions search "repo access" --all --json
|
|
6478
|
-
|
|
6479
|
-
JSON:
|
|
6480
|
-
JSON mode returns {sessions, nextCursor}. --all follows cursors until nextCursor is null.
|
|
6481
|
-
`
|
|
6482
|
-
).action((query, options, command) => searchSessionsCommand(query, options, command));
|
|
6483
6454
|
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(
|
|
6484
6455
|
"after",
|
|
6485
6456
|
`
|
|
@@ -6504,14 +6475,6 @@ Examples:
|
|
|
6504
6475
|
arcanist sessions transcript <session-id> --last 20
|
|
6505
6476
|
`
|
|
6506
6477
|
).action((sessionId, options, command) => transcriptCommand(sessionId, options, command));
|
|
6507
|
-
sessions.command("watch").description("Watch session activity until it becomes idle").argument("<session-id>", "Session ID").option("--poll-interval <ms>", "Polling interval in milliseconds", String(DEFAULT_WATCH_POLL_INTERVAL_MS)).addHelpText(
|
|
6508
|
-
"after",
|
|
6509
|
-
`
|
|
6510
|
-
Examples:
|
|
6511
|
-
arcanist sessions watch <session-id>
|
|
6512
|
-
arcanist sessions watch <session-id> --json
|
|
6513
|
-
`
|
|
6514
|
-
).action((sessionId, options, command) => watchCommand(sessionId, options, command));
|
|
6515
6478
|
sessions.command("usage").description("Get token usage for a session").argument("<session-id>", "Session ID").addHelpText(
|
|
6516
6479
|
"after",
|
|
6517
6480
|
`
|