@claudexor/cli 3.1.2 → 3.3.7-rc.0
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/about-command.d.ts.map +1 -1
- package/dist/accounts-projection.d.ts +8 -1
- package/dist/accounts-projection.d.ts.map +1 -1
- package/dist/accounts-projection.js +33 -20
- package/dist/accounts-projection.js.map +1 -1
- package/dist/accounts-services.d.ts +208 -0
- package/dist/accounts-services.d.ts.map +1 -0
- package/dist/accounts-services.js +88 -0
- package/dist/accounts-services.js.map +1 -0
- package/dist/acp-surface-runner.d.ts +39 -0
- package/dist/acp-surface-runner.d.ts.map +1 -1
- package/dist/acp-surface-runner.js +104 -30
- package/dist/acp-surface-runner.js.map +1 -1
- package/dist/attachment-upload.d.ts +5 -0
- package/dist/attachment-upload.d.ts.map +1 -0
- package/dist/attachment-upload.js +64 -0
- package/dist/attachment-upload.js.map +1 -0
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +6 -1
- package/dist/capabilities.js.map +1 -1
- package/dist/choice-input.d.ts +7 -0
- package/dist/choice-input.d.ts.map +1 -0
- package/dist/choice-input.js +17 -0
- package/dist/choice-input.js.map +1 -0
- package/dist/claude-oauth-usage.d.ts.map +1 -1
- package/dist/claude-oauth-usage.js +13 -1
- package/dist/claude-oauth-usage.js.map +1 -1
- package/dist/claudexord-entry.js.map +1 -1
- package/dist/claudexord.d.ts +1 -13
- package/dist/claudexord.d.ts.map +1 -1
- package/dist/claudexord.js +57 -94
- package/dist/claudexord.js.map +1 -1
- package/dist/cli-error.d.ts.map +1 -1
- package/dist/cli-error.js +21 -11
- package/dist/cli-error.js.map +1 -1
- package/dist/cli.js +143 -163
- package/dist/cli.js.map +1 -1
- package/dist/codex-device-login.js.map +1 -1
- package/dist/codex-quota-source.js.map +1 -1
- package/dist/command-flags.d.ts +16 -1
- package/dist/command-flags.d.ts.map +1 -1
- package/dist/command-flags.js +41 -19
- package/dist/command-flags.js.map +1 -1
- package/dist/command-registry.d.ts +21 -8
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +59 -116
- package/dist/command-registry.js.map +1 -1
- package/dist/command-scope.d.ts +13 -0
- package/dist/command-scope.d.ts.map +1 -0
- package/dist/command-scope.js +61 -0
- package/dist/command-scope.js.map +1 -0
- package/dist/control-services.d.ts +1638 -1003
- package/dist/control-services.d.ts.map +1 -1
- package/dist/control-services.js +49 -67
- package/dist/control-services.js.map +1 -1
- package/dist/credential-commands.d.ts.map +1 -1
- package/dist/credential-commands.js +13 -3
- package/dist/credential-commands.js.map +1 -1
- package/dist/daemon-lifecycle.d.ts.map +1 -1
- package/dist/daemon-outcome.d.ts +3 -5
- package/dist/daemon-outcome.d.ts.map +1 -1
- package/dist/daemon-outcome.js +7 -19
- package/dist/daemon-outcome.js.map +1 -1
- package/dist/daemon-run.d.ts +21 -12
- package/dist/daemon-run.d.ts.map +1 -1
- package/dist/daemon-run.js +59 -40
- package/dist/daemon-run.js.map +1 -1
- package/dist/daemon-runtime-shutdown.d.ts +7 -0
- package/dist/daemon-runtime-shutdown.d.ts.map +1 -1
- package/dist/daemon-runtime-shutdown.js +29 -0
- package/dist/daemon-runtime-shutdown.js.map +1 -1
- package/dist/delegation-belt-descriptor.js.map +1 -1
- package/dist/delegation-output.d.ts +2 -0
- package/dist/delegation-output.d.ts.map +1 -1
- package/dist/delegation-output.js +3 -1
- package/dist/delegation-output.js.map +1 -1
- package/dist/harness-command.d.ts +13 -0
- package/dist/harness-command.d.ts.map +1 -0
- package/dist/harness-command.js +35 -0
- package/dist/harness-command.js.map +1 -0
- package/dist/harness-installer.d.ts +79 -0
- package/dist/harness-installer.d.ts.map +1 -0
- package/dist/harness-installer.js +256 -0
- package/dist/harness-installer.js.map +1 -0
- package/dist/interaction-prompt.d.ts +19 -0
- package/dist/interaction-prompt.d.ts.map +1 -0
- package/dist/interaction-prompt.js +114 -0
- package/dist/interaction-prompt.js.map +1 -0
- package/dist/live.d.ts +2 -6
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +88 -75
- package/dist/live.js.map +1 -1
- package/dist/mcp-daemon-unavailable.d.ts +6 -0
- package/dist/mcp-daemon-unavailable.d.ts.map +1 -0
- package/dist/mcp-daemon-unavailable.js +16 -0
- package/dist/mcp-daemon-unavailable.js.map +1 -0
- package/dist/mcp-run-projections.d.ts +30 -0
- package/dist/mcp-run-projections.d.ts.map +1 -1
- package/dist/mcp-run-projections.js +17 -17
- package/dist/mcp-run-projections.js.map +1 -1
- package/dist/mcp-runner.d.ts.map +1 -1
- package/dist/mcp-runner.js +81 -39
- package/dist/mcp-runner.js.map +1 -1
- package/dist/native-login.js.map +1 -1
- package/dist/ops-command-specs.d.ts +64 -0
- package/dist/ops-command-specs.d.ts.map +1 -0
- package/dist/ops-command-specs.js +146 -0
- package/dist/ops-command-specs.js.map +1 -0
- package/dist/ops-commands.d.ts.map +1 -1
- package/dist/ops-commands.js +23 -5
- package/dist/ops-commands.js.map +1 -1
- package/dist/orphan-reaper.js.map +1 -1
- package/dist/output-mode.d.ts +11 -0
- package/dist/output-mode.d.ts.map +1 -0
- package/dist/output-mode.js +28 -0
- package/dist/output-mode.js.map +1 -0
- package/dist/plan-question-loop.d.ts.map +1 -1
- package/dist/plan-question-loop.js +17 -13
- package/dist/plan-question-loop.js.map +1 -1
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/primary-output.d.ts +9 -4
- package/dist/primary-output.d.ts.map +1 -1
- package/dist/primary-output.js +50 -2
- package/dist/primary-output.js.map +1 -1
- package/dist/quota-subject-universe.d.ts +6 -0
- package/dist/quota-subject-universe.d.ts.map +1 -0
- package/dist/quota-subject-universe.js +31 -0
- package/dist/quota-subject-universe.js.map +1 -0
- package/dist/registry.js.map +1 -1
- package/dist/release-command.d.ts +1 -1
- package/dist/release-command.js +2 -2
- package/dist/remote-command-specs.d.ts +45 -0
- package/dist/remote-command-specs.d.ts.map +1 -0
- package/dist/remote-command-specs.js +29 -0
- package/dist/remote-command-specs.js.map +1 -0
- package/dist/remote-command.d.ts +11 -0
- package/dist/remote-command.d.ts.map +1 -0
- package/dist/remote-command.js +262 -0
- package/dist/remote-command.js.map +1 -0
- package/dist/remote-filesystem.d.ts +33 -0
- package/dist/remote-filesystem.d.ts.map +1 -0
- package/dist/remote-filesystem.js +280 -0
- package/dist/remote-filesystem.js.map +1 -0
- package/dist/repo-asset-authority.js.map +1 -1
- package/dist/request-preflight.d.ts +11 -2
- package/dist/request-preflight.d.ts.map +1 -1
- package/dist/request-preflight.js +36 -13
- package/dist/request-preflight.js.map +1 -1
- package/dist/retention-service.d.ts.map +1 -1
- package/dist/retention-service.js +6 -1
- package/dist/retention-service.js.map +1 -1
- package/dist/retry-command-specs.d.ts.map +1 -1
- package/dist/retry-command-specs.js +2 -0
- package/dist/retry-command-specs.js.map +1 -1
- package/dist/run-applicability.d.ts +74 -0
- package/dist/run-applicability.d.ts.map +1 -0
- package/dist/run-applicability.js +80 -0
- package/dist/run-applicability.js.map +1 -0
- package/dist/run-detail-projections.d.ts +23 -0
- package/dist/run-detail-projections.d.ts.map +1 -1
- package/dist/run-detail-projections.js +32 -1
- package/dist/run-detail-projections.js.map +1 -1
- package/dist/run-detail-response.d.ts +7 -0
- package/dist/run-detail-response.d.ts.map +1 -0
- package/dist/run-detail-response.js +23 -0
- package/dist/run-detail-response.js.map +1 -0
- package/dist/run-facts-projection.d.ts +22 -0
- package/dist/run-facts-projection.d.ts.map +1 -0
- package/dist/run-facts-projection.js +86 -0
- package/dist/run-facts-projection.js.map +1 -0
- package/dist/runtime-replacement-stop.d.ts +25 -0
- package/dist/runtime-replacement-stop.d.ts.map +1 -0
- package/dist/runtime-replacement-stop.js +145 -0
- package/dist/runtime-replacement-stop.js.map +1 -0
- package/dist/settings-command.d.ts +1 -0
- package/dist/settings-command.d.ts.map +1 -1
- package/dist/settings-command.js +27 -21
- package/dist/settings-command.js.map +1 -1
- package/dist/settings-service.d.ts +7 -7
- package/dist/settings-service.d.ts.map +1 -1
- package/dist/settings-service.js +3 -3
- package/dist/settings-service.js.map +1 -1
- package/dist/setup-client-pty.d.ts +14 -0
- package/dist/setup-client-pty.d.ts.map +1 -0
- package/dist/setup-client-pty.js +61 -0
- package/dist/setup-client-pty.js.map +1 -0
- package/dist/setup-device-code-disclosure.d.ts +15 -0
- package/dist/setup-device-code-disclosure.d.ts.map +1 -0
- package/dist/setup-device-code-disclosure.js +52 -0
- package/dist/setup-device-code-disclosure.js.map +1 -0
- package/dist/setup-job-reducer.d.ts.map +1 -1
- package/dist/setup-job-reducer.js +1 -0
- package/dist/setup-job-reducer.js.map +1 -1
- package/dist/setup-job-store.d.ts +275 -75
- package/dist/setup-job-store.d.ts.map +1 -1
- package/dist/setup-job-store.js.map +1 -1
- package/dist/setup-job-support.js.map +1 -1
- package/dist/setup-jobs.d.ts +517 -137
- package/dist/setup-jobs.d.ts.map +1 -1
- package/dist/setup-jobs.js +68 -118
- package/dist/setup-jobs.js.map +1 -1
- package/dist/setup-lifecycle-binding.d.ts +7 -0
- package/dist/setup-lifecycle-binding.d.ts.map +1 -1
- package/dist/setup-lifecycle-binding.js +6 -0
- package/dist/setup-lifecycle-binding.js.map +1 -1
- package/dist/setup-login-child-lifecycle.d.ts +13 -0
- package/dist/setup-login-child-lifecycle.d.ts.map +1 -0
- package/dist/setup-login-child-lifecycle.js +45 -0
- package/dist/setup-login-child-lifecycle.js.map +1 -0
- package/dist/setup-login-inline.d.ts +11 -12
- package/dist/setup-login-inline.d.ts.map +1 -1
- package/dist/setup-login-inline.js +26 -15
- package/dist/setup-login-inline.js.map +1 -1
- package/dist/setup-login-permit.d.ts +10 -0
- package/dist/setup-login-permit.d.ts.map +1 -0
- package/dist/setup-login-permit.js +52 -0
- package/dist/setup-login-permit.js.map +1 -0
- package/dist/setup-login-protocol.d.ts.map +1 -1
- package/dist/setup-login-protocol.js +9 -2
- package/dist/setup-login-protocol.js.map +1 -1
- package/dist/setup-login-runner.d.ts +1 -0
- package/dist/setup-login-runner.d.ts.map +1 -1
- package/dist/setup-login-runner.js +20 -31
- package/dist/setup-login-runner.js.map +1 -1
- package/dist/setup-supervisor.d.ts.map +1 -1
- package/dist/setup-supervisor.js.map +1 -1
- package/dist/terminal-run-output.d.ts +12 -0
- package/dist/terminal-run-output.d.ts.map +1 -0
- package/dist/terminal-run-output.js +33 -0
- package/dist/terminal-run-output.js.map +1 -0
- package/dist/thread-continuity-context.d.ts +36 -0
- package/dist/thread-continuity-context.d.ts.map +1 -0
- package/dist/thread-continuity-context.js +33 -0
- package/dist/thread-continuity-context.js.map +1 -0
- package/dist/thread-execution-workspace.d.ts +15 -0
- package/dist/thread-execution-workspace.d.ts.map +1 -1
- package/dist/thread-execution-workspace.js +39 -5
- package/dist/thread-execution-workspace.js.map +1 -1
- package/dist/thread-turn-services.d.ts +107 -0
- package/dist/thread-turn-services.d.ts.map +1 -0
- package/dist/thread-turn-services.js +28 -0
- package/dist/thread-turn-services.js.map +1 -0
- package/package.json +23 -23
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import process from "node:process";
|
|
3
|
-
import {
|
|
4
|
-
import { createHash } from "node:crypto";
|
|
5
|
-
import { Readable, Transform } from "node:stream";
|
|
3
|
+
import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
|
|
6
4
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
7
5
|
import { ArtifactStore } from "@claudexor/artifact-store";
|
|
8
6
|
import { CLAUDEXOR_VERSION, noProjectRepoRoot, readTextSafe, userConfigDir } from "@claudexor/util";
|
|
@@ -10,13 +8,15 @@ import { releaseCommand } from "./release-command.js";
|
|
|
10
8
|
import { serveBeltBridge, serveMcpBridge } from "./bridge-serve.js";
|
|
11
9
|
import { dispatchAcpCommand } from "./acp-auth-command.js";
|
|
12
10
|
import { initProjectConfig } from "@claudexor/config";
|
|
13
|
-
import { DecisionRecord, EFFORT_HINT_HELP, EffortHint, ExternalContextPolicy, ModeKind as ModeKindSchema, RoutingGoal, ControlThreadListResponse, RunTelemetry, StructuredOutputConformance, TaskContract, runOutcomeLabel, } from "@claudexor/schema";
|
|
11
|
+
import { DecisionRecord, EFFORT_HINT_HELP, EffortHint, ExternalContextPolicy, ModeKind as ModeKindSchema, RoutingGoal, ControlThreadListResponse, RunFailure, RunTelemetry, StructuredOutputConformance, TaskContract, runOutcomeLabel, } from "@claudexor/schema";
|
|
14
12
|
import { flagBool, flagStr, flagStringList, flagValues, parseArgs, requiredStringFlagError, } from "./args.js";
|
|
15
13
|
import { print, printJson, printJsonLine, printUsageError, statusGlyph } from "./cli-io.js";
|
|
16
14
|
import { controlProblemError, minIntError, renderCliFailure, usageError } from "./cli-error.js";
|
|
15
|
+
import { cliOutputMode, outputModeIsMachine, outputModeIsStream, renderOutputFailure, renderOutputUsageFailure, } from "./output-mode.js";
|
|
17
16
|
import { handleHelpRequest } from "./command-help.js";
|
|
18
17
|
import { pickResumableThread } from "./thread-select.js";
|
|
19
|
-
import { KNOWN_FLAGS, VALUE_FLAGS,
|
|
18
|
+
import { KNOWN_FLAGS, VALUE_FLAGS, helpJson, renderHelp } from "./command-registry.js";
|
|
19
|
+
import { commandFlagScopeError, commandPositionalError, runModeFlagScopeError, } from "./command-scope.js";
|
|
20
20
|
import { buildAgentCapabilityCatalog } from "./capabilities.js";
|
|
21
21
|
import { aboutJson, renderAbout } from "./about-command.js";
|
|
22
22
|
import { dispatchOpsCommand } from "./ops-commands.js";
|
|
@@ -24,18 +24,22 @@ import { reviewCommand } from "./review-command.js";
|
|
|
24
24
|
import { controlApiFetch, followRun } from "./live.js";
|
|
25
25
|
import { retryCommand, runAgainCommand } from "./retry-command.js";
|
|
26
26
|
import { assertCliRunParamsHaveNoInlineSecrets } from "./run-secret-scan.js";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
27
|
+
import { resolveLocalAttachment } from "./local-attachment.js";
|
|
28
|
+
import { uploadLocalAttachment } from "./attachment-upload.js";
|
|
29
|
+
import { connectDaemonIfRunning, daemonOutcomeSummary, ensureDaemon, enqueueAndAwait, exitCodeForState, fetchApplyEligibility, fetchCouncil, fetchRunDetail, fetchRunOutcomeFacts, projectOutcomeBanner, projectRunOutcomeFacts, mergeDaemonRunOutcome, } from "./daemon-run.js";
|
|
30
|
+
import { inspectDelegationLines, projectDelegation, terminalDelegationLines, } from "./delegation-output.js";
|
|
31
|
+
import { readRunFactsArtifact } from "./run-facts-projection.js";
|
|
32
|
+
import { projectTerminalRunOutput, terminalRunRequiredActionLines } from "./terminal-run-output.js";
|
|
30
33
|
import { runPlanQuestionLoop } from "./plan-question-loop.js";
|
|
31
34
|
import { resolveDecisionBody } from "./decision.js";
|
|
32
35
|
import { primaryOutputForCli } from "./primary-output.js";
|
|
33
36
|
import { PLUGIN_TARGETS, PLUGIN_VERBS, formatPluginResult, pluginCommandErrorResult, runPluginCommand, } from "./plugins.js";
|
|
34
|
-
import { buildRegistry } from "./registry.js";
|
|
35
37
|
import { settingsCommand } from "./settings-command.js";
|
|
36
38
|
import { quotaCommand } from "./quota-command.js";
|
|
37
39
|
import { trustCommand } from "./trust-command.js";
|
|
38
40
|
import { projectCommand } from "./project-command.js";
|
|
41
|
+
import { remoteCommand, setupCommand } from "./remote-command.js";
|
|
42
|
+
import { harnessCommand } from "./harness-command.js";
|
|
39
43
|
import { runRepl } from "./repl.js";
|
|
40
44
|
import { parseProtectedPathApprovalFlags, parseTestCommandFlags, parseReviewerEffortFlags, parseReviewerModelFlags, parseReviewerPanelFlags, } from "./run-options.js";
|
|
41
45
|
const CLI_VERSION = CLAUDEXOR_VERSION;
|
|
@@ -160,55 +164,6 @@ function attachmentInputs(args) {
|
|
|
160
164
|
const out = attachmentPaths(args).map(({ path, forceImage }) => resolveLocalAttachment(path, forceImage));
|
|
161
165
|
return out.length > 0 ? out : undefined;
|
|
162
166
|
}
|
|
163
|
-
async function uploadLocalAttachment(addr, attachment) {
|
|
164
|
-
const created = (await controlJson(addr, "/uploads", {
|
|
165
|
-
method: "POST",
|
|
166
|
-
headers: { "content-type": "application/json" },
|
|
167
|
-
body: JSON.stringify({
|
|
168
|
-
kind: attachment.kind,
|
|
169
|
-
mime: attachment.mime,
|
|
170
|
-
name: attachment.name,
|
|
171
|
-
sizeBytes: attachment.sizeBytes,
|
|
172
|
-
}),
|
|
173
|
-
}));
|
|
174
|
-
try {
|
|
175
|
-
const source = createReadStream(attachment.path, {
|
|
176
|
-
fd: openLocalAttachment(attachment),
|
|
177
|
-
autoClose: true,
|
|
178
|
-
});
|
|
179
|
-
const hash = createHash("sha256");
|
|
180
|
-
const hashingStream = new Transform({
|
|
181
|
-
transform(chunk, _encoding, callback) {
|
|
182
|
-
hash.update(chunk);
|
|
183
|
-
callback(null, chunk);
|
|
184
|
-
},
|
|
185
|
-
});
|
|
186
|
-
source.pipe(hashingStream);
|
|
187
|
-
const response = await controlApiFetch(addr, `/uploads/${encodeURIComponent(created.uploadId)}/bytes`, {
|
|
188
|
-
method: "PUT",
|
|
189
|
-
headers: { "content-type": "application/octet-stream" },
|
|
190
|
-
body: Readable.toWeb(hashingStream),
|
|
191
|
-
duplex: "half",
|
|
192
|
-
});
|
|
193
|
-
if (!response.ok) {
|
|
194
|
-
const detail = (await response.json().catch(() => ({})));
|
|
195
|
-
throw new Error(String(detail["message"] ?? detail["error"] ?? `HTTP ${response.status}`));
|
|
196
|
-
}
|
|
197
|
-
const expectedSha256 = `sha256:${hash.digest("hex")}`;
|
|
198
|
-
const resource = (await controlJson(addr, `/uploads/${encodeURIComponent(created.uploadId)}/finalize`, {
|
|
199
|
-
method: "POST",
|
|
200
|
-
headers: { "content-type": "application/json" },
|
|
201
|
-
body: JSON.stringify({ expectedSha256 }),
|
|
202
|
-
}));
|
|
203
|
-
return { resourceId: resource.resourceId };
|
|
204
|
-
}
|
|
205
|
-
catch (error) {
|
|
206
|
-
await controlApiFetch(addr, `/uploads/${encodeURIComponent(created.uploadId)}`, {
|
|
207
|
-
method: "DELETE",
|
|
208
|
-
}).catch(() => undefined);
|
|
209
|
-
throw error;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
167
|
/** Per-family reviewer model map from `--reviewer-model "openai=gpt-4o-mini,anthropic=claude-haiku"`. Fails loudly on malformed input. */
|
|
213
168
|
function reviewerModels(args) {
|
|
214
169
|
return parseReviewerModelFlags(flagValues(args, "reviewer-model"));
|
|
@@ -221,7 +176,7 @@ function reviewerEfforts(args) {
|
|
|
221
176
|
function reviewerPanel(args) {
|
|
222
177
|
return parseReviewerPanelFlags(flagValues(args, "reviewer-panel"));
|
|
223
178
|
}
|
|
224
|
-
async function orchestrate(args, mode,
|
|
179
|
+
async function orchestrate(args, mode, outputMode, forced = {}) {
|
|
225
180
|
let rawPrompt = args._.slice(1).join(" ").trim();
|
|
226
181
|
// Headless prompt sources (W13): `-` reads the prompt from stdin; a file
|
|
227
182
|
// beats retyping. Exactly ONE source — ambiguity is a usage error, never a
|
|
@@ -229,34 +184,34 @@ async function orchestrate(args, mode, json, forced = {}) {
|
|
|
229
184
|
const promptFile = flagStr(args, "prompt-file");
|
|
230
185
|
if (promptFile !== undefined) {
|
|
231
186
|
if (rawPrompt && rawPrompt !== "-") {
|
|
232
|
-
return
|
|
187
|
+
return renderOutputUsageFailure(outputMode, "claudexor: pass either an inline prompt or --prompt-file, not both");
|
|
233
188
|
}
|
|
234
189
|
try {
|
|
235
190
|
rawPrompt = readFileSync(promptFile, "utf8").trim();
|
|
236
191
|
}
|
|
237
192
|
catch (err) {
|
|
238
|
-
return
|
|
193
|
+
return renderOutputUsageFailure(outputMode, `claudexor: --prompt-file: cannot read ${promptFile}: ${err instanceof Error ? err.message : String(err)}`);
|
|
239
194
|
}
|
|
240
195
|
}
|
|
241
196
|
else if (rawPrompt === "-") {
|
|
242
197
|
rawPrompt = readFileSync(0, "utf8").trim();
|
|
243
198
|
if (!rawPrompt) {
|
|
244
|
-
return
|
|
199
|
+
return renderOutputUsageFailure(outputMode, "claudexor: stdin prompt (`-`) was empty");
|
|
245
200
|
}
|
|
246
201
|
}
|
|
247
202
|
const prompt = rawPrompt;
|
|
248
203
|
if (!prompt) {
|
|
249
|
-
return
|
|
204
|
+
return renderOutputUsageFailure(outputMode, "claudexor: missing prompt");
|
|
250
205
|
}
|
|
251
206
|
const portfolioRaw = flagStr(args, "portfolio");
|
|
252
207
|
if (portfolioRaw !== undefined) {
|
|
253
|
-
return
|
|
208
|
+
return renderOutputUsageFailure(outputMode, "claudexor: --portfolio was removed in v2; use --routing-goal auto|quality|economy");
|
|
254
209
|
}
|
|
255
210
|
const credentialProfileId = flagStr(args, "profile");
|
|
256
211
|
const routingGoalRaw = flagStr(args, "routing-goal");
|
|
257
212
|
const routingGoal = routingGoalRaw !== undefined ? RoutingGoal.safeParse(routingGoalRaw) : null;
|
|
258
213
|
if (routingGoalRaw !== undefined && !routingGoal?.success) {
|
|
259
|
-
return
|
|
214
|
+
return renderOutputUsageFailure(outputMode, `claudexor: unknown --routing-goal '${routingGoalRaw}'`);
|
|
260
215
|
}
|
|
261
216
|
let reviewerEffortOverrides;
|
|
262
217
|
let resolvedReviewerModels;
|
|
@@ -333,7 +288,10 @@ async function orchestrate(args, mode, json, forced = {}) {
|
|
|
333
288
|
}
|
|
334
289
|
catch (err) {
|
|
335
290
|
// Projector: typed field errors / domain codes survive; a plain flag-parse Error is usage (exit 2).
|
|
336
|
-
return
|
|
291
|
+
return renderOutputFailure(outputMode, err, {
|
|
292
|
+
defaultCategory: "usage",
|
|
293
|
+
messagePrefix: "claudexor:",
|
|
294
|
+
});
|
|
337
295
|
}
|
|
338
296
|
let tests;
|
|
339
297
|
try {
|
|
@@ -362,15 +320,18 @@ async function orchestrate(args, mode, json, forced = {}) {
|
|
|
362
320
|
}
|
|
363
321
|
catch (err) {
|
|
364
322
|
// Preserves the typed `inline_secret_rejected` code (never echoing the token).
|
|
365
|
-
return
|
|
323
|
+
return renderOutputFailure(outputMode, err, {
|
|
324
|
+
defaultCategory: "usage",
|
|
325
|
+
messagePrefix: "claudexor:",
|
|
326
|
+
});
|
|
366
327
|
}
|
|
367
328
|
if (delegate && mode !== "agent") {
|
|
368
|
-
return
|
|
329
|
+
return renderOutputUsageFailure(outputMode, `claudexor: --delegate is an agent strategy (got mode '${mode}')`);
|
|
369
330
|
}
|
|
370
331
|
if (council && mode !== "plan") {
|
|
371
|
-
return
|
|
332
|
+
return renderOutputUsageFailure(outputMode, `claudexor: --council is a plan strategy (got mode '${mode}')`);
|
|
372
333
|
}
|
|
373
|
-
return daemonRun(args,
|
|
334
|
+
return daemonRun(args, outputMode, {
|
|
374
335
|
mode,
|
|
375
336
|
delegate,
|
|
376
337
|
council,
|
|
@@ -405,12 +366,10 @@ async function orchestrate(args, mode, json, forced = {}) {
|
|
|
405
366
|
* All five product modes enter through the managed daemon and control API.
|
|
406
367
|
* `--json` prints one stable `{ runId, runDir, status }` machine envelope.
|
|
407
368
|
*/
|
|
408
|
-
async function daemonRun(args,
|
|
369
|
+
async function daemonRun(args, outputMode, p) {
|
|
409
370
|
const inPlace = flagBool(args, "in-place");
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
return printUsageError(json, "claudexor: --json prints exactly one object and --json-stream prints NDJSON; pass one, not both");
|
|
413
|
-
}
|
|
371
|
+
const json = outputModeIsMachine(outputMode);
|
|
372
|
+
const jsonStream = outputModeIsStream(outputMode);
|
|
414
373
|
let client;
|
|
415
374
|
let addr;
|
|
416
375
|
try {
|
|
@@ -504,6 +463,10 @@ async function daemonRun(args, json, p) {
|
|
|
504
463
|
...(p.reviewerModels ? { reviewerModels: p.reviewerModels } : {}),
|
|
505
464
|
...(p.reviewerEfforts ? { reviewerEfforts: p.reviewerEfforts } : {}),
|
|
506
465
|
};
|
|
466
|
+
// The last run id this command bound, threaded into the failure envelope as
|
|
467
|
+
// a per-command extra: a run that DID start (or finish) must keep its handle
|
|
468
|
+
// even when a post-terminal read raises (e.g. 500 run_facts_invalid).
|
|
469
|
+
let terminalRunId = "";
|
|
507
470
|
try {
|
|
508
471
|
if (jsonStream) {
|
|
509
472
|
// NDJSON machine surface (W13): an EARLY runId frame first, every run
|
|
@@ -513,18 +476,10 @@ async function daemonRun(args, json, p) {
|
|
|
513
476
|
const started = await enqueueAndAwait(client, addr, body, { waitForTerminal: false });
|
|
514
477
|
if (!started.runId) {
|
|
515
478
|
// Even the early-failure path stays valid NDJSON (compact, one line).
|
|
516
|
-
printJsonLine({
|
|
517
|
-
frame: "run.terminal",
|
|
518
|
-
runId: "",
|
|
519
|
-
runDir: started.runDir,
|
|
520
|
-
status: started.status,
|
|
521
|
-
jobId: started.jobId,
|
|
522
|
-
mode: p.mode,
|
|
523
|
-
...(started.error ? { error: started.error } : {}),
|
|
524
|
-
...daemonOutcomeProblemFields(started),
|
|
525
|
-
});
|
|
479
|
+
printJsonLine(projectTerminalRunOutput(started, p.mode, null, { frame: "run.terminal" }));
|
|
526
480
|
return exitCodeForState(started.status);
|
|
527
481
|
}
|
|
482
|
+
terminalRunId = started.runId;
|
|
528
483
|
printJsonLine({
|
|
529
484
|
frame: "run.started",
|
|
530
485
|
runId: started.runId,
|
|
@@ -538,43 +493,31 @@ async function daemonRun(args, json, p) {
|
|
|
538
493
|
const final = started.jobId ? await client.status(started.jobId) : null;
|
|
539
494
|
const out = mergeDaemonRunOutcome(started, final);
|
|
540
495
|
const status = out.status;
|
|
541
|
-
const reason = daemonOutcomeSummary({ ...started, status, error: out.error });
|
|
542
496
|
const detail = await fetchRunDetail(addr, out.runId);
|
|
543
|
-
|
|
497
|
+
const facts = projectRunOutcomeFacts(detail);
|
|
498
|
+
const reason = daemonOutcomeSummary({ ...out, outcomeFacts: facts ?? undefined });
|
|
499
|
+
printJsonLine(projectTerminalRunOutput(out, p.mode, detail, {
|
|
544
500
|
frame: "run.terminal",
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
status: out.status,
|
|
548
|
-
jobId: out.jobId,
|
|
549
|
-
mode: p.mode,
|
|
550
|
-
...(out.error ? { error: out.error } : {}),
|
|
551
|
-
...daemonOutcomeProblemFields(out),
|
|
552
|
-
...(reason ? { summary: reason } : {}),
|
|
553
|
-
...terminalDetailFields(detail),
|
|
554
|
-
});
|
|
501
|
+
summary: reason,
|
|
502
|
+
}));
|
|
555
503
|
return exitCodeForState(status, projectRunOutcomeFacts(detail));
|
|
556
504
|
}
|
|
557
505
|
if (json) {
|
|
558
506
|
// Pure machine surface: await the terminal outcome and print one JSON object.
|
|
559
507
|
const out = await enqueueAndAwait(client, addr, body, { waitForTerminal: true });
|
|
560
|
-
|
|
561
|
-
const reason = daemonOutcomeSummary(out);
|
|
508
|
+
terminalRunId = out.runId;
|
|
562
509
|
// ADD-ONLY key (bench contract keeps {runId,runDir,status}): the derived
|
|
563
510
|
// apply-gate verdict, so machine callers act on truth instead of
|
|
564
511
|
// re-implying eligibility from status. ONE GET /runs/:id feeds all three
|
|
565
512
|
// terminal projections (INV-120/122).
|
|
566
513
|
const detail = await fetchRunDetail(addr, out.runId);
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
mode: p.mode,
|
|
573
|
-
...(out.error ? { error: out.error } : {}),
|
|
574
|
-
...daemonOutcomeProblemFields(out),
|
|
575
|
-
...(reason ? { summary: reason } : {}),
|
|
576
|
-
...terminalDetailFields(detail),
|
|
514
|
+
// Preserve bench keys while deriving the human summary from the same
|
|
515
|
+
// canonical receipt that feeds the machine terminal fields.
|
|
516
|
+
const reason = daemonOutcomeSummary({
|
|
517
|
+
...out,
|
|
518
|
+
outcomeFacts: projectRunOutcomeFacts(detail) ?? undefined,
|
|
577
519
|
});
|
|
520
|
+
printJson(projectTerminalRunOutput(out, p.mode, detail, { summary: reason }));
|
|
578
521
|
return exitCodeForState(out.status, projectRunOutcomeFacts(detail));
|
|
579
522
|
}
|
|
580
523
|
// Text mode: enqueue, then live-stream the run through the shared follow
|
|
@@ -583,11 +526,15 @@ async function daemonRun(args, json, p) {
|
|
|
583
526
|
const started = await enqueueAndAwait(client, addr, body, { waitForTerminal: false });
|
|
584
527
|
if (!started.runId) {
|
|
585
528
|
print(`run did not start: ${started.status}${started.error ? ` — ${started.error}` : ""}`);
|
|
529
|
+
for (const line of terminalRunRequiredActionLines(started))
|
|
530
|
+
print(line);
|
|
586
531
|
return exitCodeForState(started.status);
|
|
587
532
|
}
|
|
533
|
+
terminalRunId = started.runId;
|
|
588
534
|
await followRun(started.runId, false);
|
|
589
535
|
const final = started.jobId ? await client.status(started.jobId) : null;
|
|
590
|
-
const
|
|
536
|
+
const out = mergeDaemonRunOutcome(started, final);
|
|
537
|
+
const status = out.status;
|
|
591
538
|
const publicStatus = status;
|
|
592
539
|
print("");
|
|
593
540
|
print(`run ${started.runId} [${publicStatus}]`);
|
|
@@ -598,7 +545,11 @@ async function daemonRun(args, json, p) {
|
|
|
598
545
|
print(` ${terminalBanner}`);
|
|
599
546
|
for (const line of terminalDelegationLines(projectDelegation(terminalDetail)))
|
|
600
547
|
print(line);
|
|
601
|
-
print(` artifacts: ${
|
|
548
|
+
print(` artifacts: ${out.runDir}`);
|
|
549
|
+
if (out.error)
|
|
550
|
+
print(` error: ${out.error}`);
|
|
551
|
+
for (const line of terminalRunRequiredActionLines(out))
|
|
552
|
+
print(line);
|
|
602
553
|
// A succeeded lifecycle exits 0 — INCLUDING a "Done · needs review" run
|
|
603
554
|
// (review blocked / checks failed). The apply-eligibility verdict (state
|
|
604
555
|
// needs_review) is the ONE source for the unblock guidance (D8).
|
|
@@ -626,6 +577,7 @@ async function daemonRun(args, json, p) {
|
|
|
626
577
|
runId: started.runId,
|
|
627
578
|
interactive: !json && !jsonStream, // TTY plan turns answer inline
|
|
628
579
|
});
|
|
580
|
+
terminalRunId = effectiveRunId;
|
|
629
581
|
}
|
|
630
582
|
// Offer apply only after a positive gate; otherwise print inspect/unblock guidance.
|
|
631
583
|
const eligibility = await fetchApplyEligibility(addr, effectiveRunId);
|
|
@@ -647,9 +599,11 @@ async function daemonRun(args, json, p) {
|
|
|
647
599
|
catch (err) {
|
|
648
600
|
// D-7 projector: a typed control problem (code/retryable/context) survives
|
|
649
601
|
// intact; --json-stream stays valid NDJSON via the compact-line stream option.
|
|
602
|
+
// A run that already started keeps its handle in the envelope (extras).
|
|
650
603
|
return renderCliFailure(json || jsonStream, err, {
|
|
651
604
|
messagePrefix: "claudexor:",
|
|
652
605
|
stream: jsonStream,
|
|
606
|
+
...(terminalRunId ? { extras: { runId: terminalRunId } } : {}),
|
|
653
607
|
});
|
|
654
608
|
}
|
|
655
609
|
}
|
|
@@ -758,21 +712,12 @@ async function resolveRunStore(runId) {
|
|
|
758
712
|
}
|
|
759
713
|
return null;
|
|
760
714
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
const text = await response.text();
|
|
764
|
-
const body = text ? JSON.parse(text) : {};
|
|
765
|
-
if (response.ok)
|
|
766
|
-
return body;
|
|
767
|
-
const detail = body && typeof body === "object" ? body : {};
|
|
768
|
-
throw new Error(String(detail["message"] ?? detail["error"] ?? `HTTP ${response.status}`));
|
|
769
|
-
}
|
|
770
|
-
function printPreflightError(args, json, error) {
|
|
771
|
-
if (json && (args._[0] ?? "help") === "plugin") {
|
|
715
|
+
function printPreflightError(args, outputMode, error) {
|
|
716
|
+
if (outputMode === "json" && (args._[0] ?? "help") === "plugin") {
|
|
772
717
|
printJson(pluginCommandErrorResult(args._[1], args._[2], flagBool(args, "dry-run"), 2, error));
|
|
773
718
|
return 2;
|
|
774
719
|
}
|
|
775
|
-
return
|
|
720
|
+
return renderOutputUsageFailure(outputMode, error);
|
|
776
721
|
}
|
|
777
722
|
function listCliArtifacts(root) {
|
|
778
723
|
if (!existsSync(root))
|
|
@@ -794,8 +739,12 @@ function listCliArtifacts(root) {
|
|
|
794
739
|
// KNOWN_FLAGS / VALUE_FLAGS (imported above) and the per-command scope check
|
|
795
740
|
// are projections of the command registry. Unknown flags FAIL LOUDLY: `--harnes
|
|
796
741
|
// codex` must never silently run all harnesses.
|
|
797
|
-
async function dispatch(args,
|
|
742
|
+
async function dispatch(args, outputMode) {
|
|
798
743
|
const cmd = args._[0] ?? "help";
|
|
744
|
+
if (outputMode === "conflict") {
|
|
745
|
+
return renderOutputUsageFailure(outputMode, "claudexor: --json prints exactly one object and --json-stream prints NDJSON; pass one, not both");
|
|
746
|
+
}
|
|
747
|
+
const json = outputModeIsMachine(outputMode);
|
|
799
748
|
// `--help` resolves the COMMAND first (QA-057): scoped usage for a known verb,
|
|
800
749
|
// global help for a bare/`help` verb, a usage error (exit 2) for a typo.
|
|
801
750
|
if (flagBool(args, "help"))
|
|
@@ -803,18 +752,21 @@ async function dispatch(args, json) {
|
|
|
803
752
|
const unknownFlags = Object.keys(args.flags).filter((f) => !KNOWN_FLAGS.has(f));
|
|
804
753
|
if (unknownFlags.length > 0) {
|
|
805
754
|
const error = `claudexor: unknown flag(s): ${unknownFlags.map((f) => `--${f}`).join(", ")} (see \`claudexor help\`)`;
|
|
806
|
-
return printPreflightError(args,
|
|
755
|
+
return printPreflightError(args, outputMode, error);
|
|
807
756
|
}
|
|
808
757
|
const valueFlagError = requiredStringFlagError(args, VALUE_FLAGS);
|
|
809
758
|
if (valueFlagError)
|
|
810
|
-
return printPreflightError(args,
|
|
759
|
+
return printPreflightError(args, outputMode, valueFlagError);
|
|
811
760
|
// Registry-enforced per-command flag scope: a KNOWN flag outside the
|
|
812
761
|
// command's declared set (e.g. `plan --create`, `ask --force`) fails loudly
|
|
813
762
|
// instead of being silently ignored. Data-driven from CLI_COMMANDS for
|
|
814
763
|
// every verb (this replaced the old hand-listed plugin/--force special cases).
|
|
815
764
|
const scopeError = commandFlagScopeError(cmd, Object.keys(args.flags));
|
|
816
765
|
if (scopeError)
|
|
817
|
-
return printPreflightError(args,
|
|
766
|
+
return printPreflightError(args, outputMode, scopeError);
|
|
767
|
+
const positionalError = commandPositionalError(cmd, args._.slice(1));
|
|
768
|
+
if (positionalError)
|
|
769
|
+
return printPreflightError(args, outputMode, positionalError);
|
|
818
770
|
// No arguments at all = the interactive REPL: a thread of turns over the
|
|
819
771
|
// current project with native session continuity (chat is the normal loop).
|
|
820
772
|
if (args._.length === 0 && process.stdin.isTTY) {
|
|
@@ -835,21 +787,28 @@ async function dispatch(args, json) {
|
|
|
835
787
|
}
|
|
836
788
|
case "project":
|
|
837
789
|
return projectCommand(args, json);
|
|
790
|
+
case "remote":
|
|
791
|
+
return remoteCommand(args, json);
|
|
792
|
+
case "setup":
|
|
793
|
+
return setupCommand(args, json);
|
|
838
794
|
case "agent": {
|
|
839
795
|
const modeStr = flagStr(args, "mode");
|
|
840
796
|
if (modeStr !== undefined) {
|
|
841
797
|
const mode = normalizeMode(modeStr);
|
|
842
798
|
if (!MODES.has(mode)) {
|
|
843
|
-
return
|
|
799
|
+
return renderOutputUsageFailure(outputMode, `claudexor: unknown --mode '${modeStr}'. valid: ${[...MODES].join(", ")}`);
|
|
844
800
|
}
|
|
845
|
-
|
|
801
|
+
const modeScopeError = runModeFlagScopeError(mode, Object.keys(args.flags));
|
|
802
|
+
if (modeScopeError)
|
|
803
|
+
return printPreflightError(args, outputMode, modeScopeError);
|
|
804
|
+
return orchestrate(args, mode, outputMode);
|
|
846
805
|
}
|
|
847
|
-
return orchestrate(args, "agent",
|
|
806
|
+
return orchestrate(args, "agent", outputMode);
|
|
848
807
|
}
|
|
849
808
|
case "ask":
|
|
850
|
-
return orchestrate(args, "ask",
|
|
809
|
+
return orchestrate(args, "ask", outputMode);
|
|
851
810
|
case "best-of":
|
|
852
|
-
return orchestrate(args, "agent",
|
|
811
|
+
return orchestrate(args, "agent", outputMode, { race: true });
|
|
853
812
|
// RETIRED verb spellings hard-error with the new spelling — no silent
|
|
854
813
|
// aliases (same doctrine as retired mode ids: stale scripts fail loudly).
|
|
855
814
|
case "run":
|
|
@@ -868,12 +827,12 @@ async function dispatch(args, json) {
|
|
|
868
827
|
: cmd === "spec"
|
|
869
828
|
? "claudexor plan <prompt> then Implement (the plan lifecycle surfaces open questions and freezes the plan on implement)"
|
|
870
829
|
: "claudexor ask --deep-scan <prompt>";
|
|
871
|
-
return printPreflightError(args,
|
|
830
|
+
return printPreflightError(args, outputMode, `claudexor: the '${cmd}' verb was retired; use ${replacement}`);
|
|
872
831
|
}
|
|
873
832
|
case "plan":
|
|
874
|
-
return orchestrate(args, "plan",
|
|
833
|
+
return orchestrate(args, "plan", outputMode);
|
|
875
834
|
case "create":
|
|
876
|
-
return orchestrate(args, "agent",
|
|
835
|
+
return orchestrate(args, "agent", outputMode, { create: true });
|
|
877
836
|
case "settings":
|
|
878
837
|
return settingsCommand(args, json);
|
|
879
838
|
case "quota":
|
|
@@ -922,12 +881,23 @@ async function dispatch(args, json) {
|
|
|
922
881
|
const decision = store.readYaml(join(paths.arbitrationDir, "decision.yaml"));
|
|
923
882
|
const workProduct = store.readYaml(join(paths.finalDir, "work_product.yaml"));
|
|
924
883
|
const contract = TaskContract.safeParse(store.readYaml(join(paths.contextDir, "task.yaml")));
|
|
925
|
-
const
|
|
884
|
+
const parsedFailure = RunFailure.safeParse(store.readYaml(join(paths.finalDir, "failure.yaml")));
|
|
885
|
+
const failure = parsedFailure.success ? parsedFailure.data : null;
|
|
926
886
|
// The CLI projects the orchestrator-owned telemetry artifact and NEVER
|
|
927
887
|
// recomputes evidence from raw events (single-owner rule); a missing
|
|
928
888
|
// artifact (legacy run) renders "telemetry unavailable".
|
|
929
889
|
const parsedTelemetry = RunTelemetry.safeParse(store.readYaml(join(paths.finalDir, "telemetry.yaml")));
|
|
930
890
|
const telemetry = parsedTelemetry.success ? parsedTelemetry.data : null;
|
|
891
|
+
// GH #29: inspect reads the same immutable receipt as GET and terminal JSON.
|
|
892
|
+
const runFacts = readRunFactsArtifact(store, paths.finalDir, {
|
|
893
|
+
runId,
|
|
894
|
+
...(contract.success ? { taskId: contract.data.task_id } : {}),
|
|
895
|
+
});
|
|
896
|
+
const primary = primaryOutputForCli(paths.root, contract.success ? contract.data.mode.kind : undefined, {
|
|
897
|
+
failure,
|
|
898
|
+
lifecycle: runFacts?.outcome.lifecycle,
|
|
899
|
+
...(runFacts?.presentation ? { presentation: runFacts.presentation } : {}),
|
|
900
|
+
});
|
|
931
901
|
const toolErrors = telemetry
|
|
932
902
|
? telemetry.attempts.flatMap((a) => a.tool_errors
|
|
933
903
|
.filter((e) => !e.recovered && e.kind === "web")
|
|
@@ -949,22 +919,26 @@ async function dispatch(args, json) {
|
|
|
949
919
|
})))
|
|
950
920
|
: [];
|
|
951
921
|
const artifacts = listCliArtifacts(paths.root).filter((p) => !p.endsWith("/"));
|
|
952
|
-
const outputReadyState =
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
922
|
+
const outputReadyState = runFacts?.presentation?.state ??
|
|
923
|
+
(primary?.kind === "diagnostic"
|
|
924
|
+
? "diagnostic"
|
|
925
|
+
: primary?.text.trim()
|
|
926
|
+
? "ready"
|
|
927
|
+
: (failure ?? readTextSafe(join(paths.finalDir, "failure.yaml")))
|
|
928
|
+
? "diagnostic"
|
|
929
|
+
: "finalizing");
|
|
959
930
|
const parsedDecision = DecisionRecord.safeParse(decision);
|
|
960
931
|
const summary = readTextSafe(join(paths.finalDir, "summary.md"));
|
|
961
932
|
if (json) {
|
|
962
933
|
printJson({
|
|
963
934
|
runId,
|
|
964
935
|
runDir: paths.root,
|
|
936
|
+
lifecycle: runFacts?.outcome.lifecycle ?? null,
|
|
965
937
|
outputReadyState,
|
|
966
938
|
contract: contract.success ? contract.data : null,
|
|
967
939
|
telemetry,
|
|
940
|
+
runFacts,
|
|
941
|
+
failure,
|
|
968
942
|
toolErrors,
|
|
969
943
|
toolWarnings,
|
|
970
944
|
primaryOutput: primary,
|
|
@@ -976,6 +950,8 @@ async function dispatch(args, json) {
|
|
|
976
950
|
return summary || primary ? 0 : 1;
|
|
977
951
|
}
|
|
978
952
|
print(`run ${runId} @ ${paths.root}`);
|
|
953
|
+
if (runFacts)
|
|
954
|
+
print(`lifecycle: ${runFacts.outcome.lifecycle}`);
|
|
979
955
|
if (contract.success) {
|
|
980
956
|
print(`mode: ${contract.data.mode.kind}`);
|
|
981
957
|
print(`access: requested=${contract.data.access.requested_profile} effective=${contract.data.access.effective_profile}`);
|
|
@@ -992,6 +968,12 @@ async function dispatch(args, json) {
|
|
|
992
968
|
print(`web: policy=${contract.data.external_context.policy} required=${contract.data.external_context.web_required} evidence=unavailable (no telemetry.yaml)`);
|
|
993
969
|
}
|
|
994
970
|
print(`output: ${outputReadyState}${primary ? ` ${primary.path}` : ""}`);
|
|
971
|
+
if (failure) {
|
|
972
|
+
print(`failure: ${failure.category}${failure.code ? `/${failure.code}` : ""} phase=${failure.phase}${failure.harnessId ? ` harness=${failure.harnessId}` : ""}`);
|
|
973
|
+
print(`failure message: ${failure.safeMessage}`);
|
|
974
|
+
for (const action of failure.nextActions)
|
|
975
|
+
print(`next action: ${action}`);
|
|
976
|
+
}
|
|
995
977
|
{
|
|
996
978
|
// Structured-output contract receipt (only present when the run was
|
|
997
979
|
// started with --output-schema); projected, never re-validated here.
|
|
@@ -1148,20 +1130,8 @@ async function dispatch(args, json) {
|
|
|
1148
1130
|
throw err;
|
|
1149
1131
|
}
|
|
1150
1132
|
}
|
|
1151
|
-
case "harness":
|
|
1152
|
-
|
|
1153
|
-
if (sub === "list") {
|
|
1154
|
-
// Fakes are test fixtures, not real harnesses; `--all` reveals them.
|
|
1155
|
-
const includeFakes = flagBool(args, "all");
|
|
1156
|
-
const ids = [...buildRegistry({ includeFakes }).keys()];
|
|
1157
|
-
if (json)
|
|
1158
|
-
printJson({ harnesses: ids });
|
|
1159
|
-
else
|
|
1160
|
-
ids.forEach((id) => print(id));
|
|
1161
|
-
return 0;
|
|
1162
|
-
}
|
|
1163
|
-
return printUsageError(json, "usage: claudexor harness list [--all]");
|
|
1164
|
-
}
|
|
1133
|
+
case "harness":
|
|
1134
|
+
return harnessCommand(args, json);
|
|
1165
1135
|
case "capabilities": {
|
|
1166
1136
|
// The derived AgentCapabilityCatalog — same composer as the daemon's
|
|
1167
1137
|
// GET /agent-capabilities and the MCP claudexor_capabilities tool.
|
|
@@ -1171,6 +1141,7 @@ async function dispatch(args, json) {
|
|
|
1171
1141
|
else {
|
|
1172
1142
|
print(`claudexor ${catalog.version} — capability catalog`);
|
|
1173
1143
|
print(`modes: ${catalog.modes.join(", ")}`);
|
|
1144
|
+
print(`git: ${catalog.git.status}${catalog.git.version ? ` (${catalog.git.version})` : ""}${catalog.git.remediation ? ` — ${catalog.git.remediation}` : ""}`);
|
|
1174
1145
|
print(`available harnesses: ${catalog.availableHarnesses.join(", ") || "(none)"}`);
|
|
1175
1146
|
for (const h of catalog.harnesses) {
|
|
1176
1147
|
const model = h.configuredModel
|
|
@@ -1207,7 +1178,7 @@ async function dispatch(args, json) {
|
|
|
1207
1178
|
// callers get the ONE projector envelope (with message/code shape, no
|
|
1208
1179
|
// longer a partial {ok,exitCode,error}); text mode prints the full help.
|
|
1209
1180
|
if (json) {
|
|
1210
|
-
return
|
|
1181
|
+
return renderOutputFailure(outputMode, usageError(`claudexor: unknown command '${cmd}' (see \`claudexor help --json\`)`), {});
|
|
1211
1182
|
}
|
|
1212
1183
|
process.stderr.write(`claudexor: unknown command '${cmd}'\n\n${HELP}\n`);
|
|
1213
1184
|
return 2;
|
|
@@ -1223,18 +1194,27 @@ async function main() {
|
|
|
1223
1194
|
process.stdout.write(`${CLI_VERSION}\n`);
|
|
1224
1195
|
return 0;
|
|
1225
1196
|
}
|
|
1226
|
-
const
|
|
1197
|
+
const outputMode = cliOutputMode(args);
|
|
1227
1198
|
try {
|
|
1228
|
-
return await dispatch(args,
|
|
1199
|
+
return await dispatch(args, outputMode);
|
|
1229
1200
|
}
|
|
1230
1201
|
catch (err) {
|
|
1231
|
-
return
|
|
1202
|
+
return renderOutputFailure(outputMode, err);
|
|
1232
1203
|
}
|
|
1233
1204
|
}
|
|
1234
1205
|
main()
|
|
1235
1206
|
.then((code) => process.exit(code))
|
|
1236
1207
|
.catch((err) => {
|
|
1237
|
-
// Last-resort projector:
|
|
1238
|
-
process.
|
|
1208
|
+
// Last-resort projector: infer the complete mode even if parsing itself threw.
|
|
1209
|
+
const json = process.argv.includes("--json");
|
|
1210
|
+
const stream = process.argv.includes("--json-stream");
|
|
1211
|
+
const outputMode = json
|
|
1212
|
+
? stream
|
|
1213
|
+
? "conflict"
|
|
1214
|
+
: "json"
|
|
1215
|
+
: stream
|
|
1216
|
+
? "json-stream"
|
|
1217
|
+
: "human";
|
|
1218
|
+
process.exit(renderOutputFailure(outputMode, err));
|
|
1239
1219
|
});
|
|
1240
1220
|
//# sourceMappingURL=cli.js.map
|