@claudexor/cli 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -0
  3. package/dist/args.d.ts +12 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +88 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/attachment-resolver.d.ts +11 -0
  8. package/dist/attachment-resolver.d.ts.map +1 -0
  9. package/dist/attachment-resolver.js +61 -0
  10. package/dist/attachment-resolver.js.map +1 -0
  11. package/dist/capabilities.d.ts +13 -0
  12. package/dist/capabilities.d.ts.map +1 -0
  13. package/dist/capabilities.js +90 -0
  14. package/dist/capabilities.js.map +1 -0
  15. package/dist/claudexord.d.ts +3 -0
  16. package/dist/claudexord.d.ts.map +1 -0
  17. package/dist/claudexord.js +564 -0
  18. package/dist/claudexord.js.map +1 -0
  19. package/dist/cli-io.d.ts +28 -0
  20. package/dist/cli-io.d.ts.map +1 -0
  21. package/dist/cli-io.js +37 -0
  22. package/dist/cli-io.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +1459 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/command-registry.d.ts +105 -0
  28. package/dist/command-registry.d.ts.map +1 -0
  29. package/dist/command-registry.js +516 -0
  30. package/dist/command-registry.js.map +1 -0
  31. package/dist/daemon-lifecycle.d.ts +18 -0
  32. package/dist/daemon-lifecycle.d.ts.map +1 -0
  33. package/dist/daemon-lifecycle.js +62 -0
  34. package/dist/daemon-lifecycle.js.map +1 -0
  35. package/dist/daemon-run.d.ts +86 -0
  36. package/dist/daemon-run.d.ts.map +1 -0
  37. package/dist/daemon-run.js +269 -0
  38. package/dist/daemon-run.js.map +1 -0
  39. package/dist/decision.d.ts +18 -0
  40. package/dist/decision.d.ts.map +1 -0
  41. package/dist/decision.js +46 -0
  42. package/dist/decision.js.map +1 -0
  43. package/dist/live.d.ts +26 -0
  44. package/dist/live.d.ts.map +1 -0
  45. package/dist/live.js +311 -0
  46. package/dist/live.js.map +1 -0
  47. package/dist/mcp-runner.d.ts +41 -0
  48. package/dist/mcp-runner.d.ts.map +1 -0
  49. package/dist/mcp-runner.js +306 -0
  50. package/dist/mcp-runner.js.map +1 -0
  51. package/dist/ops-commands.d.ts +11 -0
  52. package/dist/ops-commands.d.ts.map +1 -0
  53. package/dist/ops-commands.js +358 -0
  54. package/dist/ops-commands.js.map +1 -0
  55. package/dist/orchestrate-options.d.ts +9 -0
  56. package/dist/orchestrate-options.d.ts.map +1 -0
  57. package/dist/orchestrate-options.js +16 -0
  58. package/dist/orchestrate-options.js.map +1 -0
  59. package/dist/orphan-reaper.d.ts +9 -0
  60. package/dist/orphan-reaper.d.ts.map +1 -0
  61. package/dist/orphan-reaper.js +97 -0
  62. package/dist/orphan-reaper.js.map +1 -0
  63. package/dist/orphan-sweeper.d.ts +7 -0
  64. package/dist/orphan-sweeper.d.ts.map +1 -0
  65. package/dist/orphan-sweeper.js +289 -0
  66. package/dist/orphan-sweeper.js.map +1 -0
  67. package/dist/plugins.d.ts +44 -0
  68. package/dist/plugins.d.ts.map +1 -0
  69. package/dist/plugins.js +1383 -0
  70. package/dist/plugins.js.map +1 -0
  71. package/dist/primary-output.d.ts +14 -0
  72. package/dist/primary-output.d.ts.map +1 -0
  73. package/dist/primary-output.js +34 -0
  74. package/dist/primary-output.js.map +1 -0
  75. package/dist/registry.d.ts +26 -0
  76. package/dist/registry.d.ts.map +1 -0
  77. package/dist/registry.js +71 -0
  78. package/dist/registry.js.map +1 -0
  79. package/dist/release.d.ts +14 -0
  80. package/dist/release.d.ts.map +1 -0
  81. package/dist/release.js +49 -0
  82. package/dist/release.js.map +1 -0
  83. package/dist/repl.d.ts +26 -0
  84. package/dist/repl.d.ts.map +1 -0
  85. package/dist/repl.js +277 -0
  86. package/dist/repl.js.map +1 -0
  87. package/dist/review-command.d.ts +3 -0
  88. package/dist/review-command.d.ts.map +1 -0
  89. package/dist/review-command.js +83 -0
  90. package/dist/review-command.js.map +1 -0
  91. package/dist/reviewer-options.d.ts +18 -0
  92. package/dist/reviewer-options.d.ts.map +1 -0
  93. package/dist/reviewer-options.js +110 -0
  94. package/dist/reviewer-options.js.map +1 -0
  95. package/dist/run-options.d.ts +8 -0
  96. package/dist/run-options.d.ts.map +1 -0
  97. package/dist/run-options.js +50 -0
  98. package/dist/run-options.js.map +1 -0
  99. package/dist/run-secret-scan.d.ts +2 -0
  100. package/dist/run-secret-scan.d.ts.map +1 -0
  101. package/dist/run-secret-scan.js +5 -0
  102. package/dist/run-secret-scan.js.map +1 -0
  103. package/dist/settings-command.d.ts +3 -0
  104. package/dist/settings-command.d.ts.map +1 -0
  105. package/dist/settings-command.js +202 -0
  106. package/dist/settings-command.js.map +1 -0
  107. package/dist/settings-display.d.ts +3 -0
  108. package/dist/settings-display.d.ts.map +1 -0
  109. package/dist/settings-display.js +33 -0
  110. package/dist/settings-display.js.map +1 -0
  111. package/dist/settings-service.d.ts +15 -0
  112. package/dist/settings-service.d.ts.map +1 -0
  113. package/dist/settings-service.js +91 -0
  114. package/dist/settings-service.js.map +1 -0
  115. package/dist/setup-jobs.d.ts +28 -0
  116. package/dist/setup-jobs.d.ts.map +1 -0
  117. package/dist/setup-jobs.js +477 -0
  118. package/dist/setup-jobs.js.map +1 -0
  119. package/dist/spec.d.ts +84 -0
  120. package/dist/spec.d.ts.map +1 -0
  121. package/dist/spec.js +438 -0
  122. package/dist/spec.js.map +1 -0
  123. package/dist/trust-command.d.ts +3 -0
  124. package/dist/trust-command.d.ts.map +1 -0
  125. package/dist/trust-command.js +80 -0
  126. package/dist/trust-command.js.map +1 -0
  127. package/dist/trust-services.d.ts +7 -0
  128. package/dist/trust-services.d.ts.map +1 -0
  129. package/dist/trust-services.js +35 -0
  130. package/dist/trust-services.js.map +1 -0
  131. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-command.d.ts","sourceRoot":"","sources":["../src/settings-command.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AA8B5C,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAoLtF"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * `claudexor settings show|set` — user defaults over the layered config, with
3
+ * the same strict validation the daemon settings endpoint applies: model
4
+ * values pass the harness truth source, effort passes the declared ladder,
5
+ * and routing ids must be REAL harnesses (fakes never persist).
6
+ */
7
+ import { loadConfig, updateGlobalConfig } from "@claudexor/config";
8
+ import { validateModel } from "@claudexor/core";
9
+ import { ControlSettingsSnapshot, EffortHint, GlobalConfig, Portfolio, } from "@claudexor/schema";
10
+ import { print, printJson, printUsageError } from "./cli-io.js";
11
+ import { connectDaemonIfRunning } from "./daemon-run.js";
12
+ import { buildRegistry, harnessModels } from "./registry.js";
13
+ import { daemonRuntimeDiffLines } from "./settings-display.js";
14
+ /**
15
+ * A REAL harness id (fakes excluded), for `settings set` validation. A persistent
16
+ * routing default is not an explicit per-run selection, so a `fake-*` fixture must
17
+ * never be accepted as primary/eligible (it could route ordinary runs to a fake).
18
+ */
19
+ function isKnownHarness(id) {
20
+ return buildRegistry({ includeFakes: false }).has(id);
21
+ }
22
+ async function daemonSettingsSnapshotIfRunning() {
23
+ const conn = await connectDaemonIfRunning();
24
+ if (!conn)
25
+ return null;
26
+ try {
27
+ const res = await fetch(`${conn.addr.baseUrl}/settings`, {
28
+ headers: { Authorization: `Bearer ${conn.addr.token}` },
29
+ signal: AbortSignal.timeout(1500),
30
+ });
31
+ if (!res.ok)
32
+ return null;
33
+ return ControlSettingsSnapshot.parse(await res.json());
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ export async function settingsCommand(args, json) {
40
+ const sub = args._[1] ?? "show";
41
+ if (sub === "show") {
42
+ const cfg = loadConfig(process.cwd());
43
+ if (json)
44
+ printJson(cfg);
45
+ else {
46
+ print(`sources: ${cfg.sources.length ? cfg.sources.join(", ") : "(defaults)"}`);
47
+ print(`default_portfolio: ${cfg.global.default_portfolio}`);
48
+ print(`routing.default_policy: ${cfg.global.routing.default_policy}`);
49
+ print(`routing.primary_harness: ${cfg.global.routing.primary_harness ?? "(none)"}`);
50
+ print(`routing.eligible_harnesses: ${cfg.global.routing.eligible_harnesses.length ? cfg.global.routing.eligible_harnesses.join(", ") : "(auto)"}`);
51
+ print(`routing.env_inheritance: ${cfg.global.routing.env_inheritance}`);
52
+ print(`budget.max_usd_per_run: ${cfg.global.budget.max_usd_per_run ?? "(none)"}`);
53
+ print(`interaction_timeout_ms: ${cfg.global.interaction_timeout_ms}`);
54
+ print(`runtime.reviewer_timeout_ms: ${cfg.global.runtime.reviewer_timeout_ms}`);
55
+ print(`runtime.transient_retry.max_retries: ${cfg.global.runtime.transient_retry.max_retries}`);
56
+ print(`runtime.transient_retry.initial_delay_ms: ${cfg.global.runtime.transient_retry.initial_delay_ms}`);
57
+ print(`runtime.transient_retry.max_delay_ms: ${cfg.global.runtime.transient_retry.max_delay_ms}`);
58
+ const harnessIds = Object.keys(cfg.global.harnesses);
59
+ if (harnessIds.length) {
60
+ print("harnesses:");
61
+ for (const id of harnessIds) {
62
+ const h = cfg.global.harnesses[id];
63
+ print(` ${id}: enabled=${h.enabled} model=${h.default_model ?? "(native)"} effort=${h.effort ?? "(native)"} web=${h.web} max_turns=${h.max_turns ?? "(none)"} max_usd=${h.max_usd ?? "(none)"}`);
64
+ }
65
+ }
66
+ const daemonSettings = await daemonSettingsSnapshotIfRunning();
67
+ if (daemonSettings) {
68
+ const diffLines = daemonRuntimeDiffLines(cfg, daemonSettings);
69
+ for (const line of diffLines)
70
+ print(line);
71
+ }
72
+ }
73
+ return 0;
74
+ }
75
+ if (sub === "set") {
76
+ const key = args._[2];
77
+ const value = args._[3];
78
+ if (!key || value === undefined) {
79
+ return printUsageError(json, "usage: claudexor settings set default_portfolio|primary_harness|eligible_harnesses|harness.<id>.default_model|harness.<id>.fallback_model|harness.<id>.effort|env_inheritance|routing_policy|budget_max_usd_per_run|interaction_timeout_ms <value>");
80
+ }
81
+ try {
82
+ // Harness-scoped model/effort keys (INV-103: model choice is
83
+ // harness-scoped — there is no global model setting). Values are
84
+ // validated against the harness's truth source BEFORE persisting, the
85
+ // same strict gate the daemon settings endpoint applies.
86
+ const harnessKey = /^harness\.([^.]+)\.(default_model|fallback_model|effort)$/.exec(key);
87
+ if (harnessKey) {
88
+ const [, harnessId, field] = harnessKey;
89
+ if (!isKnownHarness(harnessId))
90
+ throw new Error(`unknown harness '${harnessId}' (run \`claudexor harness list --all\`)`);
91
+ const cleared = value === "none";
92
+ if (!cleared && (field === "default_model" || field === "fallback_model")) {
93
+ const truth = await harnessModels(harnessId, process.cwd(), true);
94
+ const check = validateModel(value, truth.models.map((m) => m.id), truth.source === "api" ? "api" : "manifest");
95
+ if (check.status !== "ok") {
96
+ throw new Error(`harness '${harnessId}' refused ${field} '${value}' (truth source: ${truth.source}): ${check.message}`);
97
+ }
98
+ }
99
+ let effortValue = null;
100
+ if (!cleared && field === "effort") {
101
+ effortValue = EffortHint.parse(value);
102
+ const adapter = buildRegistry({ includeFakes: true }).get(harnessId);
103
+ const ladder = adapter ? (await adapter.discover()).capabilities.effort_levels : [];
104
+ if (!ladder.includes(effortValue)) {
105
+ throw new Error(ladder.length === 0
106
+ ? `harness '${harnessId}' declares no effort ladder; leave effort unset`
107
+ : `harness '${harnessId}' does not accept effort '${value}' (declared ladder: ${ladder.join(", ")})`);
108
+ }
109
+ }
110
+ const res = updateGlobalConfig((cfg) => {
111
+ const base = cfg.harnesses[harnessId] ??
112
+ GlobalConfig.shape.harnesses.removeDefault().valueSchema.parse({});
113
+ return {
114
+ ...cfg,
115
+ harnesses: {
116
+ ...cfg.harnesses,
117
+ [harnessId]: {
118
+ ...base,
119
+ ...(field === "default_model" ? { default_model: cleared ? null : value } : {}),
120
+ ...(field === "fallback_model" ? { fallback_model: cleared ? null : value } : {}),
121
+ ...(field === "effort" ? { effort: cleared ? null : effortValue } : {}),
122
+ },
123
+ },
124
+ };
125
+ });
126
+ if (json)
127
+ printJson(res);
128
+ else
129
+ print(`updated ${key} in ${res.path}`);
130
+ return 0;
131
+ }
132
+ const res = updateGlobalConfig((cfg) => {
133
+ if (key === "default_portfolio") {
134
+ const p = Portfolio.parse(value);
135
+ return { ...cfg, default_portfolio: p };
136
+ }
137
+ if (key === "primary_harness") {
138
+ if (value !== "none" && !isKnownHarness(value))
139
+ throw new Error(`unknown harness '${value}' (run \`claudexor harness list --all\`)`);
140
+ return {
141
+ ...cfg,
142
+ routing: { ...cfg.routing, primary_harness: value === "none" ? null : value },
143
+ };
144
+ }
145
+ if (key === "eligible_harnesses") {
146
+ const list = value === "none"
147
+ ? []
148
+ : value
149
+ .split(",")
150
+ .map((s) => s.trim())
151
+ .filter(Boolean);
152
+ const unknown = list.filter((h) => !isKnownHarness(h));
153
+ if (unknown.length)
154
+ throw new Error(`unknown harness(es): ${unknown.join(", ")} (run \`claudexor harness list --all\`)`);
155
+ return { ...cfg, routing: { ...cfg.routing, eligible_harnesses: list } };
156
+ }
157
+ if (key === "default_model") {
158
+ throw new Error("the global default_model setting was removed (model choice is harness-scoped, INV-103); use `claudexor settings set harness.<id>.default_model <model>`");
159
+ }
160
+ if (key === "env_inheritance") {
161
+ if (!["mirror_native", "clean"].includes(value))
162
+ throw new Error("env_inheritance must be mirror_native|clean");
163
+ return { ...cfg, routing: { ...cfg.routing, env_inheritance: value } };
164
+ }
165
+ if (key === "routing_policy") {
166
+ if (!["auto", "primary"].includes(value))
167
+ throw new Error("routing_policy must be auto|primary");
168
+ return { ...cfg, routing: { ...cfg.routing, default_policy: value } };
169
+ }
170
+ if (key === "budget_max_usd_per_run") {
171
+ // Number() parses the WHOLE string ('1abc' -> NaN), unlike parseFloat.
172
+ const parsed = value === "none" ? null : Number(value.trim());
173
+ if (parsed !== null && (!Number.isFinite(parsed) || parsed < 0 || value.trim() === ""))
174
+ throw new Error(`${key} must be a non-negative number or none`);
175
+ return { ...cfg, budget: { ...cfg.budget, max_usd_per_run: parsed } };
176
+ }
177
+ if (key === "interaction_timeout_ms") {
178
+ const parsed = Number(value.trim());
179
+ if (!Number.isInteger(parsed) || parsed <= 0)
180
+ throw new Error("interaction_timeout_ms must be a positive integer (milliseconds)");
181
+ return { ...cfg, interaction_timeout_ms: parsed };
182
+ }
183
+ throw new Error(`unknown setting: ${key}`);
184
+ });
185
+ if (json)
186
+ printJson(res);
187
+ else
188
+ print(`updated ${key} in ${res.path}`);
189
+ return 0;
190
+ }
191
+ catch (err) {
192
+ const message = `claudexor settings: ${err instanceof Error ? err.message : String(err)}`;
193
+ if (json)
194
+ printJson({ ok: false, exitCode: 1, error: message });
195
+ else
196
+ process.stderr.write(`${message}\n`);
197
+ return 1;
198
+ }
199
+ }
200
+ return printUsageError(json, "usage: claudexor settings show|set");
201
+ }
202
+ //# sourceMappingURL=settings-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-command.js","sourceRoot":"","sources":["../src/settings-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ControlSettingsSnapshot, ResolvedConfig } from "@claudexor/schema";
2
+ export declare function daemonRuntimeDiffLines(local: ResolvedConfig, daemon: ControlSettingsSnapshot): string[];
3
+ //# sourceMappingURL=settings-display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-display.d.ts","sourceRoot":"","sources":["../src/settings-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAQjF,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,uBAAuB,GAC9B,MAAM,EAAE,CA+BV"}
@@ -0,0 +1,33 @@
1
+ export function daemonRuntimeDiffLines(local, daemon) {
2
+ const lines = [
3
+ {
4
+ key: "interaction_timeout_ms",
5
+ local: local.global.interaction_timeout_ms,
6
+ daemon: daemon.interactionTimeoutMs,
7
+ },
8
+ {
9
+ key: "runtime.reviewer_timeout_ms",
10
+ local: local.global.runtime.reviewer_timeout_ms,
11
+ daemon: daemon.runtime?.reviewerTimeoutMs,
12
+ },
13
+ {
14
+ key: "runtime.transient_retry.max_retries",
15
+ local: local.global.runtime.transient_retry.max_retries,
16
+ daemon: daemon.runtime?.transientRetry?.maxRetries,
17
+ },
18
+ {
19
+ key: "runtime.transient_retry.initial_delay_ms",
20
+ local: local.global.runtime.transient_retry.initial_delay_ms,
21
+ daemon: daemon.runtime?.transientRetry?.initialDelayMs,
22
+ },
23
+ {
24
+ key: "runtime.transient_retry.max_delay_ms",
25
+ local: local.global.runtime.transient_retry.max_delay_ms,
26
+ daemon: daemon.runtime?.transientRetry?.maxDelayMs,
27
+ },
28
+ ];
29
+ return lines
30
+ .filter((line) => line.daemon !== undefined && line.daemon !== line.local)
31
+ .map((line) => `daemon.effective.${line.key}: ${line.daemon} (local shell: ${line.local})`);
32
+ }
33
+ //# sourceMappingURL=settings-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-display.js","sourceRoot":"","sources":["../src/settings-display.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,sBAAsB,CACpC,KAAqB,EACrB,MAA+B;IAE/B,MAAM,KAAK,GAAkB;QAC3B;YACE,GAAG,EAAE,wBAAwB;YAC7B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,sBAAsB;YAC1C,MAAM,EAAE,MAAM,CAAC,oBAAoB;SACpC;QACD;YACE,GAAG,EAAE,6BAA6B;YAClC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB;YAC/C,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,iBAAiB;SAC1C;QACD;YACE,GAAG,EAAE,qCAAqC;YAC1C,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,WAAW;YACvD,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU;SACnD;QACD;YACE,GAAG,EAAE,0CAA0C;YAC/C,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,gBAAgB;YAC5D,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,cAAc;SACvD;QACD;YACE,GAAG,EAAE,sCAAsC;YAC3C,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,YAAY;YACxD,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU;SACnD;KACF,CAAC;IACF,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC;SACzE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,oBAAoB,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,MAAM,kBAAkB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;AAChG,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Settings-write validation + patch merge — the daemon's POST /settings core.
3
+ *
4
+ * STRICT (INV-104): persisted routing ids must be REAL registered
5
+ * harnesses (fakes are test fixtures, never persistable routing targets),
6
+ * model values must pass the harness's model truth source, and effort must be
7
+ * on the declared ladder. All violations are 400s naming the harness, the
8
+ * value, and the truth source — a bad value must never be persisted to die
9
+ * later as an opaque native error.
10
+ */
11
+ import type { ControlSettingsUpdateRequest, GlobalConfig as GlobalConfigT } from "@claudexor/schema";
12
+ export declare function assertSettingsPatchValid(p: ControlSettingsUpdateRequest): Promise<void>;
13
+ /** Merge camelCase per-harness patches into the snake_case GlobalConfig shape. */
14
+ export declare function applyHarnessSettingsPatches(current: GlobalConfigT["harnesses"], patches: ControlSettingsUpdateRequest["harnesses"]): GlobalConfigT["harnesses"];
15
+ //# sourceMappingURL=settings-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-service.d.ts","sourceRoot":"","sources":["../src/settings-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,4BAA4B,EAAE,YAAY,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AASrG,wBAAsB,wBAAwB,CAAC,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE7F;AAED,kFAAkF;AAClF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,EACnC,OAAO,EAAE,4BAA4B,CAAC,WAAW,CAAC,GACjD,aAAa,CAAC,WAAW,CAAC,CAiC5B"}
@@ -0,0 +1,91 @@
1
+ import { GlobalConfig } from "@claudexor/schema";
2
+ import { validateModel } from "@claudexor/core";
3
+ import { buildRegistry, harnessModels } from "./registry.js";
4
+ function badRequest(message) {
5
+ throw Object.assign(new Error(message), { status: 400 });
6
+ }
7
+ export async function assertSettingsPatchValid(p) {
8
+ const realIds = new Set(buildRegistry({ includeFakes: false }).keys());
9
+ const realList = [...realIds].sort().join(", ");
10
+ if (p.primaryHarness) {
11
+ if (!realIds.has(p.primaryHarness)) {
12
+ badRequest(`primaryHarness '${p.primaryHarness}' is not a real registered harness (expected one of: ${realList})`);
13
+ }
14
+ }
15
+ for (const id of p.eligibleHarnesses ?? []) {
16
+ if (!realIds.has(id)) {
17
+ badRequest(`eligibleHarnesses entry '${id}' is not a real registered harness (expected one of: ${realList})`);
18
+ }
19
+ }
20
+ for (const [id, patch] of Object.entries(p.harnesses ?? {})) {
21
+ // Per-harness settings persist only for REAL harnesses too: a
22
+ // fake fixture id must fail here exactly like it does on the CLI path,
23
+ // never quietly persist a `harnesses.fake-*` block.
24
+ if (!realIds.has(id)) {
25
+ badRequest(`harness settings for '${id}' are not persistable: not a real registered harness (expected one of: ${realList})`);
26
+ }
27
+ const models = [];
28
+ if (patch.defaultModel)
29
+ models.push({ field: "defaultModel", value: patch.defaultModel });
30
+ if (patch.fallbackModel)
31
+ models.push({ field: "fallbackModel", value: patch.fallbackModel });
32
+ if (models.length > 0) {
33
+ const truth = await harnessModels(id, process.cwd(), true);
34
+ for (const { field, value } of models) {
35
+ const check = validateModel(value, truth.models.map((m) => m.id), truth.source === "api" ? "api" : "manifest");
36
+ if (check.status !== "ok") {
37
+ badRequest(`harness '${id}' refused ${field} '${value}' (truth source: ${truth.source}): ${check.message}`);
38
+ }
39
+ }
40
+ }
41
+ if (patch.effort) {
42
+ const adapter = buildRegistry().get(id);
43
+ let ladder = [];
44
+ try {
45
+ ladder = adapter ? (await adapter.discover()).capabilities.effort_levels : [];
46
+ }
47
+ catch (err) {
48
+ // A harness whose manifest cannot be discovered (binary missing) still
49
+ // 400s honestly rather than bubbling a raw error out of the endpoint.
50
+ badRequest(`cannot verify effort for '${id}': ${err instanceof Error ? err.message : String(err)}`);
51
+ }
52
+ if (!ladder.includes(patch.effort)) {
53
+ badRequest(ladder.length === 0
54
+ ? `harness '${id}' declares no effort ladder; leave effort unset`
55
+ : `harness '${id}' does not accept effort '${patch.effort}' (declared ladder: ${ladder.join(", ")})`);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ /** Merge camelCase per-harness patches into the snake_case GlobalConfig shape. */
61
+ export function applyHarnessSettingsPatches(current, patches) {
62
+ if (!patches)
63
+ return current;
64
+ // FAIL LOUDLY on unknown harness ids: a typo ('codexx') must never be
65
+ // silently persisted as a new config entry nothing will ever read. REAL
66
+ // harnesses only — fakes are test fixtures, never persistable.
67
+ const knownIds = new Set(buildRegistry({ includeFakes: false }).keys());
68
+ const next = { ...current };
69
+ for (const [id, patch] of Object.entries(patches)) {
70
+ if (!knownIds.has(id)) {
71
+ throw Object.assign(new Error(`unknown harness id '${id}' (expected one of: ${[...knownIds].sort().join(", ")})`), { status: 400 });
72
+ }
73
+ const base = next[id] ?? GlobalConfig.shape.harnesses.removeDefault().valueSchema.parse({});
74
+ next[id] = {
75
+ ...base,
76
+ enabled: patch.enabled ?? base.enabled,
77
+ default_model: patch.defaultModel === undefined ? base.default_model : patch.defaultModel,
78
+ effort: patch.effort === undefined ? base.effort : patch.effort,
79
+ max_turns: patch.maxTurns === undefined ? base.max_turns : patch.maxTurns,
80
+ max_rounds: patch.maxRounds === undefined ? base.max_rounds : patch.maxRounds,
81
+ max_usd: patch.maxUsd === undefined ? base.max_usd : patch.maxUsd,
82
+ tools_allow: patch.toolsAllow ?? base.tools_allow,
83
+ tools_deny: patch.toolsDeny ?? base.tools_deny,
84
+ fallback_model: patch.fallbackModel === undefined ? base.fallback_model : patch.fallbackModel,
85
+ web: patch.web ?? base.web,
86
+ auth_preference: patch.authPreference ?? base.auth_preference,
87
+ };
88
+ }
89
+ return next;
90
+ }
91
+ //# sourceMappingURL=settings-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-service.js","sourceRoot":"","sources":["../src/settings-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type ControlSetupJob } from "@claudexor/schema";
2
+ /** Native login command for a harness (null = API-key refs only). Single
3
+ * source for both the setup-job Terminal handoff and `claudexor auth login`. */
4
+ export declare function nativeLoginCommand(harness: string): string | null;
5
+ /** Minimal doctor view the in-process verification needs (gateway statusAll). */
6
+ export interface SetupDoctorStatus {
7
+ id: string;
8
+ status: string;
9
+ checks: {
10
+ id: string;
11
+ status: string;
12
+ }[];
13
+ reasons?: string[];
14
+ }
15
+ export interface SetupJobManagerOptions {
16
+ /** Injectable doctor probe (tests); defaults to the real gateway statusAll. */
17
+ statusAll?: () => Promise<SetupDoctorStatus[]>;
18
+ /** Override the doctor phase timeout (tests). */
19
+ doctorTimeoutMs?: number;
20
+ }
21
+ export declare function createSetupJobManager(opts?: SetupJobManagerOptions): {
22
+ create(input: unknown): ControlSetupJob;
23
+ confirm(input: unknown): ControlSetupJob;
24
+ list(): ControlSetupJob[];
25
+ status(input: unknown): ControlSetupJob;
26
+ cancel(input: unknown): ControlSetupJob;
27
+ };
28
+ //# sourceMappingURL=setup-jobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-jobs.d.ts","sourceRoot":"","sources":["../src/setup-jobs.ts"],"names":[],"mappings":"AAOA,OAAO,EAA4C,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAwDnG;gFACgF;AAChF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjE;AAYD,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC/C,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,sBAA2B;kBA4PrD,OAAO,GAAG,eAAe;mBAkFxB,OAAO,GAAG,eAAe;YAkBhC,eAAe,EAAE;kBAIX,OAAO,GAAG,eAAe;kBAQzB,OAAO,GAAG,eAAe;EAwB1C"}