@claudexor/cli 3.1.2 → 3.2.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 +206 -0
- package/dist/accounts-services.d.ts.map +1 -0
- package/dist/accounts-services.js +71 -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.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 +45 -69
- 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 +1631 -1003
- package/dist/control-services.d.ts.map +1 -1
- package/dist/control-services.js +38 -65
- 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 +29 -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 +16 -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/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 +72 -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-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 +104 -0
- package/dist/thread-turn-services.d.ts.map +1 -0
- package/dist/thread-turn-services.js +27 -0
- package/dist/thread-turn-services.js.map +1 -0
- package/package.json +23 -23
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import { type ControlPrimaryOutput as ControlPrimaryOutputType, type RunFailure as RunFailureType } from "@claudexor/schema";
|
|
2
|
+
export type PrimaryOutputPresentation = Pick<ControlPrimaryOutputType, "kind" | "path" | "text"> & {
|
|
3
|
+
truncated?: boolean;
|
|
4
|
+
};
|
|
5
|
+
/** Schema-validate the Control API's single primary-output owner. */
|
|
6
|
+
export declare function projectRunPrimaryOutput(detail: Record<string, unknown> | null): ControlPrimaryOutputType | null;
|
|
7
|
+
/** Inline non-patch output with an honest bounded-preview disclosure. */
|
|
8
|
+
export declare function presentRunPrimaryOutput(output: PrimaryOutputPresentation | null): string | null;
|
|
1
9
|
export type ApplyEligibilityProjection = {
|
|
2
10
|
eligible: boolean;
|
|
3
11
|
state: string | null;
|
|
@@ -7,10 +15,25 @@ export type ApplyEligibilityProjection = {
|
|
|
7
15
|
export declare function projectApplyEligibility(detail: Record<string, unknown> | null): ApplyEligibilityProjection | null;
|
|
8
16
|
export declare function projectRunSpendUsd(detail: Record<string, unknown> | null): number | null;
|
|
9
17
|
export declare function projectRunCouncil(detail: Record<string, unknown> | null): unknown;
|
|
18
|
+
/** Preserve only the schema-owned typed terminal failure. Every surface uses
|
|
19
|
+
* this projection instead of forwarding an arbitrary failure-shaped object. */
|
|
20
|
+
export declare function projectRunFailure(detail: Record<string, unknown> | null): RunFailureType | null;
|
|
10
21
|
export declare function projectRunLineage(detail: Record<string, unknown> | null): {
|
|
11
22
|
parentRunId: string | null;
|
|
12
23
|
delegatedFromRunId: string | null;
|
|
13
24
|
delegation: Record<string, unknown> | null;
|
|
14
25
|
};
|
|
15
26
|
export declare function projectOutcomeBanner(detail: Record<string, unknown> | null): string | null;
|
|
27
|
+
/** Typed description of a raised post-terminal run-detail problem for surfaces
|
|
28
|
+
* that must DEGRADE instead of failing the caller (MCP results, ACP turn
|
|
29
|
+
* results, --json outcome projections): the finished run's result survives with
|
|
30
|
+
* its runId, and this field discloses WHY its detail projections are absent.
|
|
31
|
+
* The CLI's own terminal path keeps the raise (renderCliFailure, non-zero
|
|
32
|
+
* exit) — there the run result IS the process outcome. */
|
|
33
|
+
export interface RunDetailProblem {
|
|
34
|
+
code: string | null;
|
|
35
|
+
message: string;
|
|
36
|
+
retryable: boolean | null;
|
|
37
|
+
}
|
|
38
|
+
export declare function describeRunDetailProblem(error: unknown): RunDetailProblem;
|
|
16
39
|
//# sourceMappingURL=run-detail-projections.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-detail-projections.d.ts","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-detail-projections.d.ts","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,oBAAoB,IAAI,wBAAwB,EACrD,KAAK,UAAU,IAAI,cAAc,EAClC,MAAM,mBAAmB,CAAC;AAG3B,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,wBAAwB,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG;IACjG,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,qEAAqE;AACrE,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACrC,wBAAwB,GAAG,IAAI,CAGjC;AAED,yEAAyE;AACzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAO/F;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACrC,0BAA0B,GAAG,IAAI,CAGnC;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAOxF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,OAAO,CAGjF;AAED;+EAC+E;AAC/E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,cAAc,GAAG,IAAI,CAG/F;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG;IACzE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C,CAcA;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG1F;AAED;;;;;0DAK0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAOzE"}
|
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
import { CouncilProjection } from "@claudexor/schema";
|
|
1
|
+
import { ControlPrimaryOutput, CouncilProjection, RunFailure, } from "@claudexor/schema";
|
|
2
|
+
import { redactSecrets } from "@claudexor/util";
|
|
3
|
+
/** Schema-validate the Control API's single primary-output owner. */
|
|
4
|
+
export function projectRunPrimaryOutput(detail) {
|
|
5
|
+
const parsed = ControlPrimaryOutput.safeParse(detail?.["primaryOutput"]);
|
|
6
|
+
return parsed.success ? parsed.data : null;
|
|
7
|
+
}
|
|
8
|
+
/** Inline non-patch output with an honest bounded-preview disclosure. */
|
|
9
|
+
export function presentRunPrimaryOutput(output) {
|
|
10
|
+
if (!output || output.kind === "patch" || typeof output.text !== "string")
|
|
11
|
+
return null;
|
|
12
|
+
const text = output.text.trim();
|
|
13
|
+
if (!text)
|
|
14
|
+
return null;
|
|
15
|
+
return output.truncated === true
|
|
16
|
+
? `${text}\n\n[Inline preview bounded; full artifact: ${output.path}]`
|
|
17
|
+
: text;
|
|
18
|
+
}
|
|
2
19
|
export function projectApplyEligibility(detail) {
|
|
3
20
|
const value = detail?.["applyEligibility"];
|
|
4
21
|
return value && typeof value === "object" ? value : null;
|
|
@@ -14,6 +31,12 @@ export function projectRunCouncil(detail) {
|
|
|
14
31
|
const parsed = CouncilProjection.safeParse(detail?.["council"]);
|
|
15
32
|
return parsed.success ? parsed.data : null;
|
|
16
33
|
}
|
|
34
|
+
/** Preserve only the schema-owned typed terminal failure. Every surface uses
|
|
35
|
+
* this projection instead of forwarding an arbitrary failure-shaped object. */
|
|
36
|
+
export function projectRunFailure(detail) {
|
|
37
|
+
const parsed = RunFailure.safeParse(detail?.["failure"]);
|
|
38
|
+
return parsed.success ? parsed.data : null;
|
|
39
|
+
}
|
|
17
40
|
export function projectRunLineage(detail) {
|
|
18
41
|
const summary = detail?.["summary"] && typeof detail["summary"] === "object"
|
|
19
42
|
? detail["summary"]
|
|
@@ -30,4 +53,12 @@ export function projectOutcomeBanner(detail) {
|
|
|
30
53
|
const banner = detail?.["outcomeBanner"];
|
|
31
54
|
return typeof banner === "string" && banner.length > 0 ? banner : null;
|
|
32
55
|
}
|
|
56
|
+
export function describeRunDetailProblem(error) {
|
|
57
|
+
const record = error && typeof error === "object" ? error : {};
|
|
58
|
+
return {
|
|
59
|
+
code: typeof record["code"] === "string" && record["code"] ? record["code"] : null,
|
|
60
|
+
message: redactSecrets(error instanceof Error ? error.message : String(error)),
|
|
61
|
+
retryable: typeof record["retryable"] === "boolean" ? record["retryable"] : null,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
33
64
|
//# sourceMappingURL=run-detail-projections.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-detail-projections.js","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"run-detail-projections.js","sourceRoot":"","sources":["../src/run-detail-projections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type JsonResponse = {
|
|
2
|
+
json(): Promise<unknown>;
|
|
3
|
+
};
|
|
4
|
+
/** Decode and schema-check a successful Control API run-detail response. */
|
|
5
|
+
export declare function readRunDetailResponse(response: JsonResponse): Promise<Record<string, unknown>>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=run-detail-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-detail-response.d.ts","sourceRoot":"","sources":["../src/run-detail-response.ts"],"names":[],"mappings":"AAGA,KAAK,YAAY,GAAG;IAAE,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC;AAEjD,4EAA4E;AAC5E,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAWlC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ControlRunDetail } from "@claudexor/schema";
|
|
2
|
+
import { CliError } from "./cli-error.js";
|
|
3
|
+
/** Decode and schema-check a successful Control API run-detail response. */
|
|
4
|
+
export async function readRunDetailResponse(response) {
|
|
5
|
+
let body;
|
|
6
|
+
try {
|
|
7
|
+
body = await response.json();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
throw invalidRunDetailResponse("run detail endpoint returned malformed JSON");
|
|
11
|
+
}
|
|
12
|
+
if (!ControlRunDetail.safeParse(body).success) {
|
|
13
|
+
throw invalidRunDetailResponse("run detail endpoint returned an invalid response");
|
|
14
|
+
}
|
|
15
|
+
return body;
|
|
16
|
+
}
|
|
17
|
+
function invalidRunDetailResponse(message) {
|
|
18
|
+
return new CliError("operational", message, {
|
|
19
|
+
code: "invalid_service_response",
|
|
20
|
+
retryable: true,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=run-detail-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-detail-response.js","sourceRoot":"","sources":["../src/run-detail-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1C,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAsB;IAEtB,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,wBAAwB,CAAC,6CAA6C,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9C,MAAM,wBAAwB,CAAC,kDAAkD,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,IAA+B,CAAC;AACzC,CAAC;AAED,SAAS,wBAAwB,CAAC,OAAe;IAC/C,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,OAAO,EAAE;QAC1C,IAAI,EAAE,0BAA0B;QAChC,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ExpectedRunFactsIdentity, type RunFacts as RunFactsType } from "@claudexor/schema";
|
|
2
|
+
import { type ApplyEligibilityProjection } from "./run-detail-projections.js";
|
|
3
|
+
type RunDetail = Record<string, unknown> | null;
|
|
4
|
+
export type { ExpectedRunFactsIdentity } from "@claudexor/schema";
|
|
5
|
+
/** Exact validated terminal receipt from an already-fetched run detail. */
|
|
6
|
+
export declare function projectRunFacts(detail: RunDetail, expected?: ExpectedRunFactsIdentity): RunFactsType | null;
|
|
7
|
+
/**
|
|
8
|
+
* Shared fields appended to both terminal machine surfaces. RunFacts is
|
|
9
|
+
* intentionally always present; only a genuinely missing legacy receipt
|
|
10
|
+
* projects to null, while present malformed data fails loudly.
|
|
11
|
+
*/
|
|
12
|
+
export declare function projectTerminalDetailFields(detail: RunDetail, expected?: ExpectedRunFactsIdentity): {
|
|
13
|
+
outcomeBanner?: string;
|
|
14
|
+
applyEligibility?: ApplyEligibilityProjection;
|
|
15
|
+
runFacts: RunFactsType | null;
|
|
16
|
+
};
|
|
17
|
+
type YamlArtifactReader = {
|
|
18
|
+
readYaml(path: string): unknown;
|
|
19
|
+
};
|
|
20
|
+
/** Read the canonical immutable RunFacts artifact without reconstructing it. */
|
|
21
|
+
export declare function readRunFactsArtifact(reader: YamlArtifactReader, finalDir: string, expected?: ExpectedRunFactsIdentity): RunFactsType | null;
|
|
22
|
+
//# sourceMappingURL=run-facts-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-facts-projection.d.ts","sourceRoot":"","sources":["../src/run-facts-projection.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,IAAI,YAAY,EAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,6BAA6B,CAAC;AAErC,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;AAKhD,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,2EAA2E;AAC3E,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,wBAA6B,GACtC,YAAY,GAAG,IAAI,CAKrB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,wBAA6B,GACtC;IACD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;CAC/B,CAQA;AAED,KAAK,kBAAkB,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,wBAA6B,GACtC,YAAY,GAAG,IAAI,CAmBrB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { lstatSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { RunFactsInvalidError, validateRunFactsReceipt, } from "@claudexor/schema";
|
|
4
|
+
import { projectApplyEligibility, projectOutcomeBanner, } from "./run-detail-projections.js";
|
|
5
|
+
/** Exact validated terminal receipt from an already-fetched run detail. */
|
|
6
|
+
export function projectRunFacts(detail, expected = {}) {
|
|
7
|
+
if (!detail)
|
|
8
|
+
return null;
|
|
9
|
+
const value = detail["runFacts"];
|
|
10
|
+
if (value === null || value === undefined)
|
|
11
|
+
return null;
|
|
12
|
+
return validateRunFactsReceipt(value, expectedIdentityFromDetail(detail, expected));
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Shared fields appended to both terminal machine surfaces. RunFacts is
|
|
16
|
+
* intentionally always present; only a genuinely missing legacy receipt
|
|
17
|
+
* projects to null, while present malformed data fails loudly.
|
|
18
|
+
*/
|
|
19
|
+
export function projectTerminalDetailFields(detail, expected = {}) {
|
|
20
|
+
const outcomeBanner = projectOutcomeBanner(detail);
|
|
21
|
+
const applyEligibility = projectApplyEligibility(detail);
|
|
22
|
+
return {
|
|
23
|
+
...(outcomeBanner ? { outcomeBanner } : {}),
|
|
24
|
+
...(applyEligibility ? { applyEligibility } : {}),
|
|
25
|
+
runFacts: projectRunFacts(detail, expected),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Read the canonical immutable RunFacts artifact without reconstructing it. */
|
|
29
|
+
export function readRunFactsArtifact(reader, finalDir, expected = {}) {
|
|
30
|
+
const path = join(finalDir, "run_facts.yaml");
|
|
31
|
+
const finalDirStat = lstatOrNull(finalDir);
|
|
32
|
+
if (finalDirStat === null)
|
|
33
|
+
return null;
|
|
34
|
+
if (!finalDirStat.isDirectory() || finalDirStat.isSymbolicLink()) {
|
|
35
|
+
throw new RunFactsInvalidError();
|
|
36
|
+
}
|
|
37
|
+
const artifactStat = lstatOrNull(path);
|
|
38
|
+
if (artifactStat === null)
|
|
39
|
+
return null;
|
|
40
|
+
if (!artifactStat.isFile() || artifactStat.isSymbolicLink())
|
|
41
|
+
throw new RunFactsInvalidError();
|
|
42
|
+
let raw;
|
|
43
|
+
try {
|
|
44
|
+
raw = reader.readYaml(path);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
throw new RunFactsInvalidError();
|
|
48
|
+
}
|
|
49
|
+
return validateRunFactsReceipt(raw, expected);
|
|
50
|
+
}
|
|
51
|
+
function expectedIdentityFromDetail(detail, expected) {
|
|
52
|
+
const summary = detail["summary"];
|
|
53
|
+
if (!summary || typeof summary !== "object")
|
|
54
|
+
return expected;
|
|
55
|
+
const record = summary;
|
|
56
|
+
const summaryRunId = typeof record["runId"] === "string" ? record["runId"] : undefined;
|
|
57
|
+
const summaryTaskId = typeof record["taskId"] === "string" ? record["taskId"] : undefined;
|
|
58
|
+
if ((expected.runId !== undefined &&
|
|
59
|
+
summaryRunId !== undefined &&
|
|
60
|
+
expected.runId !== summaryRunId) ||
|
|
61
|
+
(expected.taskId !== undefined &&
|
|
62
|
+
summaryTaskId !== undefined &&
|
|
63
|
+
expected.taskId !== summaryTaskId)) {
|
|
64
|
+
throw new RunFactsInvalidError();
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
runId: expected.runId ?? summaryRunId,
|
|
68
|
+
taskId: expected.taskId ?? summaryTaskId,
|
|
69
|
+
...(expected.lifecycle !== undefined ? { lifecycle: expected.lifecycle } : {}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function lstatOrNull(path) {
|
|
73
|
+
try {
|
|
74
|
+
return lstatSync(path);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error &&
|
|
78
|
+
typeof error === "object" &&
|
|
79
|
+
"code" in error &&
|
|
80
|
+
error.code === "ENOENT") {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
throw new RunFactsInvalidError();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=run-facts-projection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-facts-projection.js","sourceRoot":"","sources":["../src/run-facts-projection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type AwaitDaemonTerminationOptions, type DaemonTerminationOutcome, type DaemonLeaseOwner, DaemonClient, awaitDaemonTermination } from "@claudexor/daemon";
|
|
2
|
+
interface RuntimeReplacementStopDeps {
|
|
3
|
+
socketPath(): string;
|
|
4
|
+
readToken(): string | null;
|
|
5
|
+
socketAlive(path: string): Promise<boolean>;
|
|
6
|
+
leaseOwner(path: string): DaemonLeaseOwner | null;
|
|
7
|
+
client(path: string, token: string): Pick<DaemonClient, "shutdownForRuntimeReplacement">;
|
|
8
|
+
awaitTermination(path: string, options: AwaitDaemonTerminationOptions): ReturnType<typeof awaitDaemonTermination>;
|
|
9
|
+
write(line: string): void;
|
|
10
|
+
}
|
|
11
|
+
/** One owner for the admission/termination uncertainty boundary used by both
|
|
12
|
+
* local and remote runtime replacement. Only a proven
|
|
13
|
+
* `{ok:true,fenced:true,targetBound:true}` receipt grants
|
|
14
|
+
* signal authority for the pre-RPC writer-lease owner.
|
|
15
|
+
* A lost, legacy, or untyped response may passively prove that the pinned
|
|
16
|
+
* daemon exited, but can never turn into a kill. */
|
|
17
|
+
export declare function admitAndAwaitRuntimeReplacementStop(requestAdmission: () => Promise<unknown>, awaitTermination: (options: AwaitDaemonTerminationOptions) => Promise<DaemonTerminationOutcome>, expectedOwner: DaemonLeaseOwner): Promise<DaemonTerminationOutcome>;
|
|
18
|
+
/** Handle `claudexord --stop`: the identity-proven, admission-safe shutdown the
|
|
19
|
+
* macOS installer runs before an atomic pointer swap. Unlike explicit operator
|
|
20
|
+
* shutdown, this asks the daemon to atomically prove idle and fence every ingress
|
|
21
|
+
* before stopping. The pinned termination proof remains authoritative when the
|
|
22
|
+
* accepted RPC response is lost as the socket closes. */
|
|
23
|
+
export declare function runStopIfRequested(argv: readonly string[], deps?: RuntimeReplacementStopDeps): Promise<boolean>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=runtime-replacement-stop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-replacement-stop.d.ts","sourceRoot":"","sources":["../src/runtime-replacement-stop.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,YAAY,EAGZ,sBAAsB,EAIvB,MAAM,mBAAmB,CAAC;AAE3B,UAAU,0BAA0B;IAClC,UAAU,IAAI,MAAM,CAAC;IACrB,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,+BAA+B,CAAC,CAAC;IACzF,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,6BAA6B,GACrC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAC7C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAoED;;;;;oDAKoD;AACpD,wBAAsB,mCAAmC,CACvD,gBAAgB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EACxC,gBAAgB,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,OAAO,CAAC,wBAAwB,CAAC,EAC/F,aAAa,EAAE,gBAAgB,GAC9B,OAAO,CAAC,wBAAwB,CAAC,CAgCnC;AAED;;;;yDAIyD;AACzD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,GAAE,0BAA2C,GAChD,OAAO,CAAC,OAAO,CAAC,CAwElB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { DaemonClient, daemonLeaseOwner, awaitDaemonTermination, defaultSocketPath, readToken, socketAlive, } from "@claudexor/daemon";
|
|
2
|
+
const productionDeps = {
|
|
3
|
+
socketPath: defaultSocketPath,
|
|
4
|
+
readToken,
|
|
5
|
+
socketAlive,
|
|
6
|
+
leaseOwner: daemonLeaseOwner,
|
|
7
|
+
client: (path, token) => new DaemonClient(path, token),
|
|
8
|
+
awaitTermination: awaitDaemonTermination,
|
|
9
|
+
write: (line) => process.stdout.write(line),
|
|
10
|
+
};
|
|
11
|
+
function refusalCode(error) {
|
|
12
|
+
if (!error || typeof error !== "object" || !("code" in error))
|
|
13
|
+
return null;
|
|
14
|
+
const code = error.code;
|
|
15
|
+
return code === "runtime_replacement_busy" || code === "runtime_activity_unknown" ? code : null;
|
|
16
|
+
}
|
|
17
|
+
function activityUnknown(message, cause) {
|
|
18
|
+
return Object.assign(new Error(message), {
|
|
19
|
+
code: "runtime_activity_unknown",
|
|
20
|
+
status: 503,
|
|
21
|
+
retryable: true,
|
|
22
|
+
...(cause === undefined ? {} : { cause }),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function isTargetBoundAdmissionReceipt(value) {
|
|
26
|
+
return (!!value &&
|
|
27
|
+
typeof value === "object" &&
|
|
28
|
+
value.ok === true &&
|
|
29
|
+
value.fenced === true &&
|
|
30
|
+
value.targetBound === true);
|
|
31
|
+
}
|
|
32
|
+
function stopIdentity(argv) {
|
|
33
|
+
const stop = argv.indexOf("--stop");
|
|
34
|
+
if (stop < 0 || argv.length !== stop + 3)
|
|
35
|
+
return null;
|
|
36
|
+
const version = argv[stop + 1];
|
|
37
|
+
const buildSha = argv[stop + 2];
|
|
38
|
+
if (typeof version !== "string" ||
|
|
39
|
+
version.length === 0 ||
|
|
40
|
+
typeof buildSha !== "string" ||
|
|
41
|
+
!/^[0-9a-f]{40}$/.test(buildSha)) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return { version, buildSha };
|
|
45
|
+
}
|
|
46
|
+
function writeRefusal(deps, code, detail) {
|
|
47
|
+
deps.write(`${JSON.stringify({ stopped: false, code, retryable: true, detail })}\n`);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
}
|
|
50
|
+
/** One owner for the admission/termination uncertainty boundary used by both
|
|
51
|
+
* local and remote runtime replacement. Only a proven
|
|
52
|
+
* `{ok:true,fenced:true,targetBound:true}` receipt grants
|
|
53
|
+
* signal authority for the pre-RPC writer-lease owner.
|
|
54
|
+
* A lost, legacy, or untyped response may passively prove that the pinned
|
|
55
|
+
* daemon exited, but can never turn into a kill. */
|
|
56
|
+
export async function admitAndAwaitRuntimeReplacementStop(requestAdmission, awaitTermination, expectedOwner) {
|
|
57
|
+
let admitted = false;
|
|
58
|
+
let admissionFailure;
|
|
59
|
+
try {
|
|
60
|
+
const receipt = await requestAdmission();
|
|
61
|
+
if (isTargetBoundAdmissionReceipt(receipt)) {
|
|
62
|
+
admitted = true;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// A pre-v3.2 daemon can accept the same method while ignoring its new
|
|
66
|
+
// identity parameters and return the legacy fenced receipt. It may still
|
|
67
|
+
// exit naturally, but it never grants signal authority to the caller.
|
|
68
|
+
admissionFailure = activityUnknown("runtime replacement returned no identity-bound admission receipt");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (refusalCode(error))
|
|
73
|
+
throw error;
|
|
74
|
+
admissionFailure = error;
|
|
75
|
+
}
|
|
76
|
+
const termination = await awaitTermination({
|
|
77
|
+
allowSigkill: admitted,
|
|
78
|
+
expectedOwner,
|
|
79
|
+
requireNoSuccessor: true,
|
|
80
|
+
});
|
|
81
|
+
if (!admitted && termination.outcome !== "exited") {
|
|
82
|
+
throw activityUnknown(`runtime replacement admission is uncertain and the daemon remains alive: ${termination.detail}`, admissionFailure);
|
|
83
|
+
}
|
|
84
|
+
return termination;
|
|
85
|
+
}
|
|
86
|
+
/** Handle `claudexord --stop`: the identity-proven, admission-safe shutdown the
|
|
87
|
+
* macOS installer runs before an atomic pointer swap. Unlike explicit operator
|
|
88
|
+
* shutdown, this asks the daemon to atomically prove idle and fence every ingress
|
|
89
|
+
* before stopping. The pinned termination proof remains authoritative when the
|
|
90
|
+
* accepted RPC response is lost as the socket closes. */
|
|
91
|
+
export async function runStopIfRequested(argv, deps = productionDeps) {
|
|
92
|
+
if (!argv.includes("--stop"))
|
|
93
|
+
return false;
|
|
94
|
+
const expectedIdentity = stopIdentity(argv);
|
|
95
|
+
if (!expectedIdentity) {
|
|
96
|
+
writeRefusal(deps, "runtime_activity_unknown", "runtime replacement requires an exact expected version and build SHA");
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
const socketPath = deps.socketPath();
|
|
100
|
+
const alive = await deps.socketAlive(socketPath);
|
|
101
|
+
if (!alive) {
|
|
102
|
+
// A daemon claims the writer lease before it binds the socket. Treating the
|
|
103
|
+
// boot window as absence would let the installer move the runtime pointer
|
|
104
|
+
// beneath that live process. Idempotent success therefore requires both
|
|
105
|
+
// surfaces to prove absence, matching the remote replacement path.
|
|
106
|
+
if (deps.leaseOwner(socketPath)) {
|
|
107
|
+
writeRefusal(deps, "runtime_activity_unknown", "runtime replacement found a writer lease but no reachable daemon socket");
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
deps.write(`${JSON.stringify({ stopped: true, alreadyStopped: true })}\n`);
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
const token = deps.readToken();
|
|
114
|
+
if (!token) {
|
|
115
|
+
writeRefusal(deps, "runtime_activity_unknown", "runtime replacement cannot authenticate to the live daemon");
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
const expectedOwner = deps.leaseOwner(socketPath);
|
|
119
|
+
if (!expectedOwner) {
|
|
120
|
+
writeRefusal(deps, "runtime_activity_unknown", "runtime replacement cannot bind the live daemon to its writer lease");
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
const expectedTarget = {
|
|
124
|
+
...expectedIdentity,
|
|
125
|
+
leaseOwner: { pid: expectedOwner.pid, token: expectedOwner.token },
|
|
126
|
+
};
|
|
127
|
+
let termination;
|
|
128
|
+
try {
|
|
129
|
+
termination = await admitAndAwaitRuntimeReplacementStop(() => deps.client(socketPath, token).shutdownForRuntimeReplacement(expectedTarget), (options) => deps.awaitTermination(socketPath, options), expectedOwner);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
const code = refusalCode(error);
|
|
133
|
+
if (code) {
|
|
134
|
+
writeRefusal(deps, code, error.message);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
const stopped = termination.outcome !== "still_alive";
|
|
140
|
+
deps.write(`${JSON.stringify({ stopped, outcome: termination.outcome, detail: termination.detail })}\n`);
|
|
141
|
+
if (!stopped)
|
|
142
|
+
process.exitCode = 1;
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=runtime-replacement-stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-replacement-stop.js","sourceRoot":"","sources":["../src/runtime-replacement-stop.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,4 +38,5 @@ export declare const HARNESS_SETTING_FIELDS: {
|
|
|
38
38
|
};
|
|
39
39
|
export declare function settingsCommand(args: ParsedArgs, json: boolean): Promise<number>;
|
|
40
40
|
export declare function settingPatch(key: string, value: string): SettingsPatch;
|
|
41
|
+
export declare function formatInteractionTimeoutSetting(value: number | null): string;
|
|
41
42
|
//# sourceMappingURL=settings-command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-command.d.ts","sourceRoot":"","sources":["../src/settings-command.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,EAGL,KAAK,4BAA4B,IAAI,aAAa,EACnD,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"settings-command.d.ts","sourceRoot":"","sources":["../src/settings-command.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,EAGL,KAAK,4BAA4B,IAAI,aAAa,EACnD,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;aAChC,YAAY,EAAE,aAAa;aAC3B,aAAa,EAAE,cAAc;aAC7B,aAAa,EAAE,cAAc;aAC7B,sBAAsB,EAAE,sBAAsB;aAC9C,eAAe,EAAE,gBAAgB;aACjC,kBAAkB,EAAE,mBAAmB;aACvC,eAAe,EAAE,gBAAgB;aACjC,mBAAmB,EAAE,kBAAkB;aACvC,eAAe,EAAE,gBAAgB;CACzB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,sBAAsB;aACjC,OAAO,EAAE,SAAS;aAClB,0BAA0B,EAAE,0BAA0B;aACtD,aAAa,EAAE,cAAc;aAC7B,cAAc,EAAE,eAAe;aAC/B,MAAM,EAAE,QAAQ;aAChB,SAAS,EAAE,UAAU;aACrB,UAAU,EAAE,WAAW;aACvB,WAAW,EAAE,YAAY;aACzB,UAAU,EAAE,WAAW;aACvB,GAAG,EAAE,KAAK;aACV,eAAe,EAAE,gBAAgB;aACjC,oBAAoB,EAAE,oBAAoB;CAClC,CAAC;AAYX,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BtF;AAmFD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CA8DtE;AAkCD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5E"}
|
package/dist/settings-command.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** `claudexor settings` is a thin projection of the daemon-owned /v2/settings surface. */
|
|
2
2
|
import { ControlSettingsSnapshot, ControlSettingsUpdateRequest, } from "@claudexor/schema";
|
|
3
3
|
import { print, printJson, printUsageError } from "./cli-io.js";
|
|
4
|
-
import { renderCliFailure } from "./cli-error.js";
|
|
4
|
+
import { controlProblemError, renderCliFailure, usageError } from "./cli-error.js";
|
|
5
5
|
import { ensureDaemon } from "./daemon-run.js";
|
|
6
6
|
import { controlApiFetch } from "./live.js";
|
|
7
7
|
/**
|
|
@@ -42,12 +42,21 @@ export const HARNESS_SETTING_FIELDS = {
|
|
|
42
42
|
const HARNESS_KEY_RE = new RegExp(`^harness\\.([^.]+)\\.(${Object.keys(HARNESS_SETTING_FIELDS).join("|")})$`);
|
|
43
43
|
const USAGE = "usage: claudexor settings set <key> <value>\n" +
|
|
44
44
|
` global keys: ${Object.keys(GLOBAL_SETTING_FIELDS).join(", ")}\n` +
|
|
45
|
+
" interaction_timeout_ms: positive milliseconds or disabled\n" +
|
|
45
46
|
` harness keys: harness.<id>.{${Object.keys(HARNESS_SETTING_FIELDS).join(",")}}`;
|
|
46
47
|
export async function settingsCommand(args, json) {
|
|
47
48
|
const sub = args._[1] ?? "show";
|
|
48
49
|
if (sub !== "show" && sub !== "set")
|
|
49
50
|
return printUsageError(json, "usage: claudexor settings show|set");
|
|
51
|
+
const key = args._[2];
|
|
52
|
+
const value = args._[3];
|
|
53
|
+
if (sub === "set" && (!key || value === undefined))
|
|
54
|
+
return printUsageError(json, USAGE);
|
|
50
55
|
try {
|
|
56
|
+
// Validate caller-owned input before daemon bootstrap. A bad key/value is a
|
|
57
|
+
// usage failure even when the engine is offline; starting the daemon cannot
|
|
58
|
+
// make malformed input valid.
|
|
59
|
+
const patch = sub === "set" ? settingPatch(key, value) : undefined;
|
|
51
60
|
const { addr } = await ensureDaemon();
|
|
52
61
|
if (sub === "show") {
|
|
53
62
|
const snapshot = await settingsRequest(addr, "GET");
|
|
@@ -57,11 +66,7 @@ export async function settingsCommand(args, json) {
|
|
|
57
66
|
printSettings(snapshot);
|
|
58
67
|
return 0;
|
|
59
68
|
}
|
|
60
|
-
const
|
|
61
|
-
const value = args._[3];
|
|
62
|
-
if (!key || value === undefined)
|
|
63
|
-
return printUsageError(json, USAGE);
|
|
64
|
-
const snapshot = await settingsRequest(addr, "POST", settingPatch(key, value));
|
|
69
|
+
const snapshot = await settingsRequest(addr, "POST", patch);
|
|
65
70
|
if (json)
|
|
66
71
|
printJson(snapshot);
|
|
67
72
|
else
|
|
@@ -90,12 +95,7 @@ async function settingsRequest(addr, method, body) {
|
|
|
90
95
|
throw new Error(`settings endpoint returned invalid JSON (HTTP ${response.status})`);
|
|
91
96
|
}
|
|
92
97
|
if (!response.ok) {
|
|
93
|
-
|
|
94
|
-
throw new Error(typeof detail["message"] === "string"
|
|
95
|
-
? detail["message"]
|
|
96
|
-
: typeof detail["error"] === "string"
|
|
97
|
-
? detail["error"]
|
|
98
|
-
: `settings request failed (HTTP ${response.status})`);
|
|
98
|
+
throw controlProblemError(response.status, value, `settings request failed (HTTP ${response.status})`);
|
|
99
99
|
}
|
|
100
100
|
return ControlSettingsSnapshot.parse(value);
|
|
101
101
|
}
|
|
@@ -107,12 +107,12 @@ function harnessFieldPatch(field, value) {
|
|
|
107
107
|
switch (field) {
|
|
108
108
|
case "enabled": {
|
|
109
109
|
if (value !== "true" && value !== "false")
|
|
110
|
-
throw
|
|
110
|
+
throw usageError("harness enabled must be true or false");
|
|
111
111
|
return { enabled: value === "true" };
|
|
112
112
|
}
|
|
113
113
|
case "native_credentials_enabled": {
|
|
114
114
|
if (value !== "true" && value !== "false")
|
|
115
|
-
throw
|
|
115
|
+
throw usageError("harness native_credentials_enabled must be true or false");
|
|
116
116
|
return { nativeCredentialsEnabled: value === "true" };
|
|
117
117
|
}
|
|
118
118
|
case "default_model":
|
|
@@ -128,7 +128,7 @@ function harnessFieldPatch(field, value) {
|
|
|
128
128
|
return { [patchKey]: null };
|
|
129
129
|
const n = Number(value.trim());
|
|
130
130
|
if (!Number.isInteger(n) || n <= 0)
|
|
131
|
-
throw
|
|
131
|
+
throw usageError(`harness ${field} must be a positive integer or none`);
|
|
132
132
|
return { [patchKey]: n };
|
|
133
133
|
}
|
|
134
134
|
case "tools_allow":
|
|
@@ -152,7 +152,7 @@ function harnessFieldPatch(field, value) {
|
|
|
152
152
|
}
|
|
153
153
|
export function settingPatch(key, value) {
|
|
154
154
|
if (key === "default_model") {
|
|
155
|
-
throw
|
|
155
|
+
throw usageError("the global default_model setting was removed (model choice is harness-scoped, INV-103); use `claudexor settings set harness.<id>.default_model <model>`");
|
|
156
156
|
}
|
|
157
157
|
const harness = HARNESS_KEY_RE.exec(key);
|
|
158
158
|
if (harness) {
|
|
@@ -163,7 +163,7 @@ export function settingPatch(key, value) {
|
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
165
|
if (key === "default_portfolio") {
|
|
166
|
-
throw
|
|
166
|
+
throw usageError("default_portfolio was removed in v2; use routing_goal");
|
|
167
167
|
}
|
|
168
168
|
if (key === "routing_goal")
|
|
169
169
|
return ControlSettingsUpdateRequest.parse({ routingGoal: value });
|
|
@@ -177,7 +177,7 @@ export function settingPatch(key, value) {
|
|
|
177
177
|
qualityTiers = JSON.parse(value);
|
|
178
178
|
}
|
|
179
179
|
catch {
|
|
180
|
-
throw
|
|
180
|
+
throw usageError("quality_tiers must be a JSON object of per-intent ordered tiers");
|
|
181
181
|
}
|
|
182
182
|
return ControlSettingsUpdateRequest.parse({ qualityTiers });
|
|
183
183
|
}
|
|
@@ -199,16 +199,19 @@ export function settingPatch(key, value) {
|
|
|
199
199
|
return ControlSettingsUpdateRequest.parse({ paidBudgetPerRun: { kind: "unlimited" } });
|
|
200
200
|
const maxUsd = Number(value.trim());
|
|
201
201
|
if (!Number.isFinite(maxUsd) || maxUsd < 0 || value.trim() === "")
|
|
202
|
-
throw
|
|
202
|
+
throw usageError(`${key} must be a non-negative number or unlimited`);
|
|
203
203
|
return ControlSettingsUpdateRequest.parse({
|
|
204
204
|
paidBudgetPerRun: { kind: "finite", maxUsd },
|
|
205
205
|
});
|
|
206
206
|
}
|
|
207
207
|
if (key === "interaction_timeout_ms") {
|
|
208
|
+
if (value.trim() === "disabled") {
|
|
209
|
+
return ControlSettingsUpdateRequest.parse({ interactionTimeoutMs: null });
|
|
210
|
+
}
|
|
208
211
|
const interactionTimeoutMs = Number(value.trim());
|
|
209
212
|
return ControlSettingsUpdateRequest.parse({ interactionTimeoutMs });
|
|
210
213
|
}
|
|
211
|
-
throw
|
|
214
|
+
throw usageError(`unknown setting: ${key}`);
|
|
212
215
|
}
|
|
213
216
|
function printSettings(settings) {
|
|
214
217
|
print(`sources: ${settings.sources.length ? settings.sources.join(", ") : "(defaults)"}`);
|
|
@@ -219,7 +222,7 @@ function printSettings(settings) {
|
|
|
219
222
|
print(`routing.env_inheritance: ${settings.routing.envInheritance}`);
|
|
220
223
|
print(`routing.auth_preference: ${settings.routing.authPreference}`);
|
|
221
224
|
print(`budget.paid_budget_per_run: ${settings.budget.paidBudgetPerRun.kind === "unlimited" ? "unlimited" : settings.budget.paidBudgetPerRun.maxUsd}`);
|
|
222
|
-
print(`interaction_timeout_ms: ${settings.interactionTimeoutMs}`);
|
|
225
|
+
print(`interaction_timeout_ms: ${formatInteractionTimeoutSetting(settings.interactionTimeoutMs)}`);
|
|
223
226
|
print(`runtime.reviewer_timeout_ms: ${settings.runtime.reviewerTimeoutMs}`);
|
|
224
227
|
print(`runtime.transient_retry.max_retries: ${settings.runtime.transientRetry.maxRetries}`);
|
|
225
228
|
print(`runtime.transient_retry.initial_delay_ms: ${settings.runtime.transientRetry.initialDelayMs}`);
|
|
@@ -232,4 +235,7 @@ function printSettings(settings) {
|
|
|
232
235
|
print(` ${id}: enabled=${harness.enabled} cli_login=${harness.nativeCredentialsEnabled ? "on" : "off"} model=${harness.defaultModel ?? "(native)"} fallback=${harness.fallbackModel ?? "(none)"} effort=${harness.effort ?? "(native)"} web=${harness.web} max_turns=${harness.maxTurns ?? "(none)"} max_rounds=${harness.maxRounds ?? "(default)"} auth=${harness.authPreference} limit_action=${harness.profileLimitAction}`);
|
|
233
236
|
}
|
|
234
237
|
}
|
|
238
|
+
export function formatInteractionTimeoutSetting(value) {
|
|
239
|
+
return value === null ? "disabled" : String(value);
|
|
240
|
+
}
|
|
235
241
|
//# sourceMappingURL=settings-command.js.map
|