@tryarcanist/cli 0.1.89 → 0.1.90
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 +269 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -383,6 +383,255 @@ async function whoamiCommand(options, command) {
|
|
|
383
383
|
if (payload.tokenScope) console.log(`Token scope: ${String(payload.tokenScope)}`);
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
// ../../shared/agent/agent-runtime-backend.ts
|
|
387
|
+
var CODEX_AGENT_RUNTIME_BACKEND = "codex";
|
|
388
|
+
var CLAUDE_CODE_AGENT_RUNTIME_BACKEND = "claude_code";
|
|
389
|
+
var AGENT_RUNTIME_BACKENDS = [
|
|
390
|
+
CODEX_AGENT_RUNTIME_BACKEND,
|
|
391
|
+
CLAUDE_CODE_AGENT_RUNTIME_BACKEND
|
|
392
|
+
];
|
|
393
|
+
function isAgentRuntimeBackend(value) {
|
|
394
|
+
return AGENT_RUNTIME_BACKENDS.includes(value);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// ../../shared/utils/type-guards.ts
|
|
398
|
+
function isRecord(value) {
|
|
399
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
400
|
+
}
|
|
401
|
+
function asNonEmptyString(value) {
|
|
402
|
+
if (typeof value !== "string") return void 0;
|
|
403
|
+
const trimmed = value.trim();
|
|
404
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// ../../shared/constants/models.ts
|
|
408
|
+
var OpenAIModel = {
|
|
409
|
+
GPT55: "gpt-5.5",
|
|
410
|
+
GPT54: "gpt-5.4",
|
|
411
|
+
GPT54Pro: "gpt-5.4-pro",
|
|
412
|
+
GPT54Mini: "gpt-5.4-mini",
|
|
413
|
+
GPT54Nano: "gpt-5.4-nano",
|
|
414
|
+
GPT53Codex: "gpt-5.3-codex",
|
|
415
|
+
GPT52: "gpt-5.2",
|
|
416
|
+
GPT52ChatLatest: "gpt-5.2-chat-latest",
|
|
417
|
+
GPT52Codex: "gpt-5.2-codex"
|
|
418
|
+
};
|
|
419
|
+
var AnthropicModel = {
|
|
420
|
+
Opus48: "claude-opus-4-8",
|
|
421
|
+
Sonnet46: "claude-sonnet-4-6"
|
|
422
|
+
};
|
|
423
|
+
var MODEL_PROVIDERS_SET = /* @__PURE__ */ new Set(["openai", "anthropic"]);
|
|
424
|
+
var SESSION_START_MODEL_IDS_BY_BACKEND = {
|
|
425
|
+
[CODEX_AGENT_RUNTIME_BACKEND]: [OpenAIModel.GPT55, OpenAIModel.GPT54],
|
|
426
|
+
[CLAUDE_CODE_AGENT_RUNTIME_BACKEND]: [AnthropicModel.Opus48, AnthropicModel.Sonnet46]
|
|
427
|
+
};
|
|
428
|
+
var DEFAULT_SESSION_START_MODEL_ID_BY_BACKEND = {
|
|
429
|
+
[CODEX_AGENT_RUNTIME_BACKEND]: OpenAIModel.GPT55,
|
|
430
|
+
[CLAUDE_CODE_AGENT_RUNTIME_BACKEND]: AnthropicModel.Opus48
|
|
431
|
+
};
|
|
432
|
+
var SESSION_START_MODEL_IDS = SESSION_START_MODEL_IDS_BY_BACKEND[CODEX_AGENT_RUNTIME_BACKEND];
|
|
433
|
+
var DEFAULT_SESSION_START_MODEL_ID = DEFAULT_SESSION_START_MODEL_ID_BY_BACKEND[CODEX_AGENT_RUNTIME_BACKEND];
|
|
434
|
+
var MODEL_REGISTRY = [
|
|
435
|
+
{
|
|
436
|
+
id: OpenAIModel.GPT55,
|
|
437
|
+
name: "GPT-5.5",
|
|
438
|
+
provider: "openai",
|
|
439
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
440
|
+
contextWindow: 1e6,
|
|
441
|
+
reasoning: { efforts: ["none", "low", "medium", "high", "xhigh"], default: "medium" }
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
id: OpenAIModel.GPT54,
|
|
445
|
+
name: "GPT-5.4",
|
|
446
|
+
provider: "openai",
|
|
447
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
448
|
+
contextWindow: 1e6,
|
|
449
|
+
reasoning: { efforts: ["none", "low", "medium", "high", "xhigh"], default: void 0 }
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
id: OpenAIModel.GPT54Mini,
|
|
453
|
+
name: "GPT-5.4 Mini",
|
|
454
|
+
provider: "openai",
|
|
455
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
456
|
+
contextWindow: 4e5,
|
|
457
|
+
reasoning: { efforts: ["none", "low", "medium", "high", "xhigh"], default: void 0 }
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
id: OpenAIModel.GPT54Nano,
|
|
461
|
+
name: "GPT-5.4 Nano",
|
|
462
|
+
provider: "openai",
|
|
463
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
464
|
+
contextWindow: 4e5,
|
|
465
|
+
reasoning: { efforts: ["none", "low", "medium", "high", "xhigh"], default: void 0 }
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
id: OpenAIModel.GPT53Codex,
|
|
469
|
+
name: "GPT-5.3 Codex",
|
|
470
|
+
provider: "openai",
|
|
471
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
472
|
+
contextWindow: 4e5,
|
|
473
|
+
reasoning: { efforts: ["low", "medium", "high", "xhigh"], default: "high" }
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
id: OpenAIModel.GPT52,
|
|
477
|
+
name: "GPT-5.2",
|
|
478
|
+
provider: "openai",
|
|
479
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
480
|
+
contextWindow: 4e5,
|
|
481
|
+
reasoning: { efforts: ["none", "low", "medium", "high", "xhigh"], default: void 0 }
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
id: OpenAIModel.GPT52ChatLatest,
|
|
485
|
+
name: "GPT-5.2 Chat",
|
|
486
|
+
provider: "openai",
|
|
487
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
488
|
+
contextWindow: 128e3,
|
|
489
|
+
reasoning: { efforts: ["none", "low", "medium", "high", "xhigh"], default: void 0 }
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
id: OpenAIModel.GPT52Codex,
|
|
493
|
+
name: "GPT-5.2 Codex",
|
|
494
|
+
provider: "openai",
|
|
495
|
+
backends: [CODEX_AGENT_RUNTIME_BACKEND],
|
|
496
|
+
contextWindow: 4e5,
|
|
497
|
+
reasoning: { efforts: ["low", "medium", "high", "xhigh"], default: "high" }
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
id: AnthropicModel.Opus48,
|
|
501
|
+
name: "Claude Opus 4.8",
|
|
502
|
+
provider: "anthropic",
|
|
503
|
+
backends: [CLAUDE_CODE_AGENT_RUNTIME_BACKEND],
|
|
504
|
+
contextWindow: 1e6
|
|
505
|
+
// Claude Code drives thinking depth itself; the bridge does not pass a
|
|
506
|
+
// reasoning-effort flag to `claude -p`, so no reasoning config is exposed.
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
id: AnthropicModel.Sonnet46,
|
|
510
|
+
name: "Claude Sonnet 4.6",
|
|
511
|
+
provider: "anthropic",
|
|
512
|
+
backends: [CLAUDE_CODE_AGENT_RUNTIME_BACKEND],
|
|
513
|
+
contextWindow: 1e6
|
|
514
|
+
}
|
|
515
|
+
];
|
|
516
|
+
var MODEL_PROVIDER_NAMES = {
|
|
517
|
+
openai: "OpenAI",
|
|
518
|
+
anthropic: "Anthropic"
|
|
519
|
+
};
|
|
520
|
+
var VALID_MODEL_IDS = new Set(MODEL_REGISTRY.map((model) => model.id));
|
|
521
|
+
var VALID_SESSION_START_MODEL_IDS_BY_BACKEND = {
|
|
522
|
+
[CODEX_AGENT_RUNTIME_BACKEND]: new Set(SESSION_START_MODEL_IDS_BY_BACKEND[CODEX_AGENT_RUNTIME_BACKEND]),
|
|
523
|
+
[CLAUDE_CODE_AGENT_RUNTIME_BACKEND]: new Set(
|
|
524
|
+
SESSION_START_MODEL_IDS_BY_BACKEND[CLAUDE_CODE_AGENT_RUNTIME_BACKEND]
|
|
525
|
+
)
|
|
526
|
+
};
|
|
527
|
+
var VALID_SESSION_START_MODEL_IDS = VALID_SESSION_START_MODEL_IDS_BY_BACKEND[CODEX_AGENT_RUNTIME_BACKEND];
|
|
528
|
+
var MODEL_CONTEXT_WINDOWS = {
|
|
529
|
+
...Object.fromEntries(
|
|
530
|
+
MODEL_REGISTRY.flatMap((model) => model.contextWindow === void 0 ? [] : [[model.id, model.contextWindow]])
|
|
531
|
+
)
|
|
532
|
+
};
|
|
533
|
+
var MODEL_PROVIDERS = {
|
|
534
|
+
...Object.fromEntries(MODEL_REGISTRY.map((model) => [model.id, model.provider]))
|
|
535
|
+
};
|
|
536
|
+
var MODEL_REASONING_CONFIG = Object.fromEntries(
|
|
537
|
+
MODEL_REGISTRY.flatMap((model) => model.reasoning ? [[model.id, model.reasoning]] : [])
|
|
538
|
+
);
|
|
539
|
+
var MODELS_WITHOUT_REASONING = /* @__PURE__ */ new Set([
|
|
540
|
+
...MODEL_REGISTRY.filter((model) => !model.reasoning).map((model) => model.id)
|
|
541
|
+
]);
|
|
542
|
+
var MODEL_DEFINITIONS_BY_ID = Object.fromEntries(MODEL_REGISTRY.map((model) => [model.id, model]));
|
|
543
|
+
function splitModelIdentifier(value) {
|
|
544
|
+
let hasSeparator = false;
|
|
545
|
+
for (const separator of [":", "/"]) {
|
|
546
|
+
const index = value.indexOf(separator);
|
|
547
|
+
if (index <= 0 || index >= value.length - 1) continue;
|
|
548
|
+
hasSeparator = true;
|
|
549
|
+
const providerID = value.slice(0, index);
|
|
550
|
+
const modelID = value.slice(index + 1);
|
|
551
|
+
if (MODEL_PROVIDERS_SET.has(providerID) && modelID.length > 0) {
|
|
552
|
+
return { providerID, modelID };
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (hasSeparator) return void 0;
|
|
556
|
+
return value.length > 0 ? { modelID: value } : void 0;
|
|
557
|
+
}
|
|
558
|
+
function getRawModelValue(raw) {
|
|
559
|
+
if (typeof raw === "string") return asNonEmptyString(raw);
|
|
560
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
561
|
+
const value = raw;
|
|
562
|
+
return asNonEmptyString(value.modelID) ?? asNonEmptyString(value.modelId) ?? asNonEmptyString(value.id);
|
|
563
|
+
}
|
|
564
|
+
function getExplicitProvider(raw) {
|
|
565
|
+
if (raw && typeof raw === "object") {
|
|
566
|
+
const value = raw;
|
|
567
|
+
const providerID = asNonEmptyString(value.providerID) ?? asNonEmptyString(value.providerId);
|
|
568
|
+
if (providerID && MODEL_PROVIDERS_SET.has(providerID)) {
|
|
569
|
+
return providerID;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
const modelValue = getRawModelValue(raw);
|
|
573
|
+
if (!modelValue) return void 0;
|
|
574
|
+
return splitModelIdentifier(modelValue)?.providerID;
|
|
575
|
+
}
|
|
576
|
+
function extractModelId(raw) {
|
|
577
|
+
const value = getRawModelValue(raw);
|
|
578
|
+
if (!value) return void 0;
|
|
579
|
+
return splitModelIdentifier(value)?.modelID;
|
|
580
|
+
}
|
|
581
|
+
function getSessionStartModelIdsForBackend(backend) {
|
|
582
|
+
return SESSION_START_MODEL_IDS_BY_BACKEND[backend];
|
|
583
|
+
}
|
|
584
|
+
function isSessionStartModelAllowedForBackend(modelId, backend) {
|
|
585
|
+
return VALID_SESSION_START_MODEL_IDS_BY_BACKEND[backend].has(modelId);
|
|
586
|
+
}
|
|
587
|
+
function getProviderForModel(modelId) {
|
|
588
|
+
return MODEL_PROVIDERS[modelId] ?? "openai";
|
|
589
|
+
}
|
|
590
|
+
function toModelSelection(raw) {
|
|
591
|
+
const modelID = extractModelId(raw);
|
|
592
|
+
if (!modelID) return void 0;
|
|
593
|
+
return {
|
|
594
|
+
providerID: getExplicitProvider(raw) ?? getProviderForModel(modelID),
|
|
595
|
+
modelID
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function getModelDefinition(raw) {
|
|
599
|
+
const modelID = extractModelId(raw);
|
|
600
|
+
if (!modelID) return void 0;
|
|
601
|
+
return MODEL_DEFINITIONS_BY_ID[modelID];
|
|
602
|
+
}
|
|
603
|
+
function formatModelLabel(raw, options = {}) {
|
|
604
|
+
const includeProvider = options.includeProvider ?? false;
|
|
605
|
+
const definition = getModelDefinition(raw);
|
|
606
|
+
if (definition) {
|
|
607
|
+
return includeProvider ? `${MODEL_PROVIDER_NAMES[definition.provider]} / ${definition.name}` : definition.name;
|
|
608
|
+
}
|
|
609
|
+
const selection = toModelSelection(raw);
|
|
610
|
+
if (!selection) return void 0;
|
|
611
|
+
const providerName = MODEL_PROVIDER_NAMES[selection.providerID];
|
|
612
|
+
return includeProvider ? `${providerName} / ${selection.modelID}` : selection.modelID;
|
|
613
|
+
}
|
|
614
|
+
function buildModelProviderGroups(models) {
|
|
615
|
+
const groups = /* @__PURE__ */ new Map();
|
|
616
|
+
for (const model of models) {
|
|
617
|
+
let group = groups.get(model.provider);
|
|
618
|
+
if (!group) {
|
|
619
|
+
group = { id: model.provider, name: MODEL_PROVIDER_NAMES[model.provider], models: [] };
|
|
620
|
+
groups.set(model.provider, group);
|
|
621
|
+
}
|
|
622
|
+
group.models.push({
|
|
623
|
+
id: model.id,
|
|
624
|
+
name: model.name,
|
|
625
|
+
label: formatModelLabel(model, { includeProvider: true }) ?? model.name,
|
|
626
|
+
reasoning: model.reasoning
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
return [...groups.values()];
|
|
630
|
+
}
|
|
631
|
+
var SESSION_START_MODEL_PROVIDER_GROUPS = buildModelProviderGroups(
|
|
632
|
+
MODEL_REGISTRY.filter((model) => VALID_SESSION_START_MODEL_IDS.has(model.id))
|
|
633
|
+
);
|
|
634
|
+
|
|
386
635
|
// ../../shared/utils/timing.ts
|
|
387
636
|
function sleep(ms) {
|
|
388
637
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -606,11 +855,6 @@ function noChangeOutcomeCopy(reason) {
|
|
|
606
855
|
}
|
|
607
856
|
}
|
|
608
857
|
|
|
609
|
-
// ../../shared/utils/type-guards.ts
|
|
610
|
-
function isRecord(value) {
|
|
611
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
858
|
// ../../shared/transcript/malformed-search.ts
|
|
615
859
|
var MALFORMED_SEARCH_BLOCKED_TRANSCRIPT_PREFIX = "Arcanist blocked this malformed search command before execution.";
|
|
616
860
|
var BASH_UNMATCHED_QUOTE_EOF_RE = /\/bin\/bash:\s+-c:\s+line\s+\d+:\s+unexpected EOF while looking for matching [`'"][`'"]?/i;
|
|
@@ -2084,6 +2328,23 @@ async function waitForCreatedPrompt(sessionId, promptId, sessionUrl, pollInterva
|
|
|
2084
2328
|
async function createCommand(repoUrl, promptArg, options, command) {
|
|
2085
2329
|
const runtime = getRuntimeOptions(command, options);
|
|
2086
2330
|
const config = requireConfig(runtime);
|
|
2331
|
+
let agentRuntimeBackend = CODEX_AGENT_RUNTIME_BACKEND;
|
|
2332
|
+
if (options.backend !== void 0) {
|
|
2333
|
+
if (!isAgentRuntimeBackend(options.backend)) {
|
|
2334
|
+
throw new CliError("user", `Invalid --backend '${options.backend}'. Expected codex or claude_code.`);
|
|
2335
|
+
}
|
|
2336
|
+
agentRuntimeBackend = options.backend;
|
|
2337
|
+
}
|
|
2338
|
+
if (options.model !== void 0) {
|
|
2339
|
+
const normalizedModel = extractModelId(options.model);
|
|
2340
|
+
if (normalizedModel === void 0 || !isSessionStartModelAllowedForBackend(normalizedModel, agentRuntimeBackend)) {
|
|
2341
|
+
const allowed = getSessionStartModelIdsForBackend(agentRuntimeBackend).join(", ");
|
|
2342
|
+
throw new CliError(
|
|
2343
|
+
"user",
|
|
2344
|
+
`Model '${options.model}' is not selectable for backend '${agentRuntimeBackend}'. Allowed: ${allowed}.`
|
|
2345
|
+
);
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2087
2348
|
const prompt = await resolvePromptInput(promptArg, options);
|
|
2088
2349
|
const waitPollIntervalMs = options.wait ? parsePollInterval(options.pollInterval) : null;
|
|
2089
2350
|
const repoError = validateRepoUrl(repoUrl);
|
|
@@ -2100,6 +2361,7 @@ async function createCommand(repoUrl, promptArg, options, command) {
|
|
|
2100
2361
|
body: JSON.stringify({
|
|
2101
2362
|
context: { repoUrl },
|
|
2102
2363
|
...options.model ? { model: options.model } : {},
|
|
2364
|
+
...options.backend ? { agentRuntimeBackend } : {},
|
|
2103
2365
|
...options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {},
|
|
2104
2366
|
...options.cold ? { cold: true } : {}
|
|
2105
2367
|
})
|
|
@@ -2141,6 +2403,7 @@ async function createCommand(repoUrl, promptArg, options, command) {
|
|
|
2141
2403
|
...sessionData.sessionUrl ? { sessionUrl: sessionData.sessionUrl } : {},
|
|
2142
2404
|
repoUrl,
|
|
2143
2405
|
...options.model ? { model: options.model } : {},
|
|
2406
|
+
...options.backend ? { agentRuntimeBackend } : {},
|
|
2144
2407
|
...options.reasoningEffort ? { reasoningEffort: options.reasoningEffort } : {},
|
|
2145
2408
|
...promptId ? { promptId } : {}
|
|
2146
2409
|
});
|
|
@@ -2566,7 +2829,7 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
|
2566
2829
|
applyColorEnvironment(getRuntimeOptions(actionCommand));
|
|
2567
2830
|
});
|
|
2568
2831
|
function addCreateOptions(cmd) {
|
|
2569
|
-
return cmd.argument("<repo-url>", "Repository URL").argument("[prompt]", "Prompt to send, or '-' to read stdin").option("--model <model>", "Model to use").option("--reasoning-effort <effort>", "Reasoning effort to use for models that support it").option("--prompt-stdin", "Read prompt from stdin").option(
|
|
2832
|
+
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: codex (default) or claude_code").option("--reasoning-effort <effort>", "Reasoning effort to use for models that support it").option("--prompt-stdin", "Read prompt from stdin").option(
|
|
2570
2833
|
"--uploaded-file <path>",
|
|
2571
2834
|
"Attach a local text file to the prompt as uploadedFiles; repeat for multiple files",
|
|
2572
2835
|
collectUploadedFileOption
|