@iowarp/clio-coder 0.3.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.
Files changed (226) hide show
  1. package/CHANGELOG.md +407 -0
  2. package/CODE_OF_CONDUCT.md +21 -0
  3. package/CONTRIBUTING.md +224 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +9 -0
  6. package/README.md +798 -0
  7. package/SECURITY.md +72 -0
  8. package/assets/clio-coder-logo-128.webp +0 -0
  9. package/damage-control-rules.yaml +419 -0
  10. package/dist/acp-UMLFVA3F.js +92 -0
  11. package/dist/agents-Q4MYPMUW.js +91 -0
  12. package/dist/auth-O6HYIJ6J.js +521 -0
  13. package/dist/chunk-262G75JS.js +35 -0
  14. package/dist/chunk-26BZQOAD.js +1281 -0
  15. package/dist/chunk-2J63S4SF.js +508 -0
  16. package/dist/chunk-3DANZDGR.js +717 -0
  17. package/dist/chunk-4UQA7NCT.js +29 -0
  18. package/dist/chunk-527KG6XR.js +497 -0
  19. package/dist/chunk-5LDRNKX2.js +1063 -0
  20. package/dist/chunk-5N2FG33Q.js +25 -0
  21. package/dist/chunk-67MTHP2E.js +135 -0
  22. package/dist/chunk-6CWDTGUC.js +20 -0
  23. package/dist/chunk-7BHLZB3A.js +2115 -0
  24. package/dist/chunk-7RBKDI66.js +348 -0
  25. package/dist/chunk-AMFR5YA3.js +541 -0
  26. package/dist/chunk-BBUH4VAA.js +1224 -0
  27. package/dist/chunk-BYEU76JP.js +899 -0
  28. package/dist/chunk-CLJ5HLUD.js +458 -0
  29. package/dist/chunk-D5YD55AR.js +116 -0
  30. package/dist/chunk-DXQNI4PC.js +61 -0
  31. package/dist/chunk-E3NYWENM.js +1004 -0
  32. package/dist/chunk-GNGDQYDU.js +34688 -0
  33. package/dist/chunk-GOTUR54M.js +9 -0
  34. package/dist/chunk-HBU5MTAM.js +41 -0
  35. package/dist/chunk-HMYNFFY4.js +28 -0
  36. package/dist/chunk-JPOWPFCU.js +1010 -0
  37. package/dist/chunk-JWHCJDCI.js +1215 -0
  38. package/dist/chunk-KBR4MZZR.js +41 -0
  39. package/dist/chunk-KKKPTZLM.js +93 -0
  40. package/dist/chunk-ME6DNWIU.js +66 -0
  41. package/dist/chunk-NI4DEJMC.js +88 -0
  42. package/dist/chunk-O4EJEDHO.js +659 -0
  43. package/dist/chunk-PIDUD6M2.js +31 -0
  44. package/dist/chunk-PS4PFJQP.js +29459 -0
  45. package/dist/chunk-QV47YRF4.js +48 -0
  46. package/dist/chunk-RQDWMVRB.js +279 -0
  47. package/dist/chunk-TFSSEXL6.js +136 -0
  48. package/dist/chunk-TKHQ4DGZ.js +8290 -0
  49. package/dist/chunk-TPOCL34A.js +2876 -0
  50. package/dist/chunk-UGYAX5YI.js +565 -0
  51. package/dist/chunk-UHTSULZS.js +461 -0
  52. package/dist/chunk-UU3R62TT.js +128 -0
  53. package/dist/chunk-UWIJNAOB.js +3906 -0
  54. package/dist/chunk-VOO7NYPP.js +914 -0
  55. package/dist/chunk-VPAWTYLY.js +117 -0
  56. package/dist/chunk-WD6AJM35.js +1216 -0
  57. package/dist/chunk-X3BR7HWV.js +115 -0
  58. package/dist/chunk-X3NE4WVW.js +120 -0
  59. package/dist/chunk-XNISANGE.js +1395 -0
  60. package/dist/chunk-XV4ZJ6ZM.js +3177 -0
  61. package/dist/cli/index.js +236 -0
  62. package/dist/clio-KIQ5SNDS.js +53 -0
  63. package/dist/components-JVHMUBEB.js +653 -0
  64. package/dist/config-ZFCDBMDC.js +372 -0
  65. package/dist/configure-G4E3A2PG.js +27 -0
  66. package/dist/context-CDXTP2MP.js +293 -0
  67. package/dist/context-E3KIFVXI.js +185 -0
  68. package/dist/context-clear-3F4PLXOS.js +102 -0
  69. package/dist/context-index-Q7YSYTR3.js +106 -0
  70. package/dist/docs-YIETIWZI.js +280 -0
  71. package/dist/doctor-M5HJJZOL.js +61 -0
  72. package/dist/domains/agents/builtins/architect.md +33 -0
  73. package/dist/domains/agents/builtins/coder.md +31 -0
  74. package/dist/domains/agents/builtins/context-bootstrap.md +38 -0
  75. package/dist/domains/agents/builtins/debugger.md +30 -0
  76. package/dist/domains/agents/builtins/documenter.md +31 -0
  77. package/dist/domains/agents/builtins/git-master.md +30 -0
  78. package/dist/domains/agents/builtins/provenance.md +30 -0
  79. package/dist/domains/agents/builtins/researcher.md +71 -0
  80. package/dist/domains/agents/builtins/scout.md +42 -0
  81. package/dist/domains/agents/builtins/tester.md +31 -0
  82. package/dist/domains/agents/builtins/verifier.md +30 -0
  83. package/dist/domains/agents/builtins/wiki-writer.md +41 -0
  84. package/dist/eval-B3KZZESM.js +2674 -0
  85. package/dist/evidence-V67CHM35.js +233 -0
  86. package/dist/evolve-YDZSUQYA.js +518 -0
  87. package/dist/extensions-SRG7XCAH.js +207 -0
  88. package/dist/fleet-CA2CRTVG.js +760 -0
  89. package/dist/fleet-preflight-CLIAX7YR.js +21 -0
  90. package/dist/init-2OZDJE2D.js +227 -0
  91. package/dist/memory-3PIQQAKX.js +207 -0
  92. package/dist/models-DY35XI7Y.js +237 -0
  93. package/dist/paths-5OMXW7Z4.js +57 -0
  94. package/dist/preload-KZVHET2B.js +11 -0
  95. package/dist/reset-PIFYNOS3.js +216 -0
  96. package/dist/run-3VSPP24F.js +735 -0
  97. package/dist/share-D36RQCXM.js +241 -0
  98. package/dist/skills-F2MRLELY.js +445 -0
  99. package/dist/skills-eval-E2ZTW4PL.js +932 -0
  100. package/dist/targets-DZMEZAH4.js +977 -0
  101. package/dist/trace-7NYCUI2J.js +250 -0
  102. package/dist/uninstall-AD3JWHBB.js +322 -0
  103. package/dist/upgrade-WYYBKGDY.js +301 -0
  104. package/dist/usage-ULIDAGFF.js +755 -0
  105. package/dist/version-ROZ6CZKH.js +16 -0
  106. package/dist/wiki-generate-PKFIX6OB.js +377 -0
  107. package/dist/worker/entry.js +1739 -0
  108. package/docs/README.md +93 -0
  109. package/docs/acp.md +120 -0
  110. package/docs/alcf-provider.md +72 -0
  111. package/docs/architecture.md +172 -0
  112. package/docs/artifact-versions.md +54 -0
  113. package/docs/built-in-agents.md +265 -0
  114. package/docs/capacity-and-scheduling.md +97 -0
  115. package/docs/commands-and-modes.md +554 -0
  116. package/docs/config-knobs-audit.md +115 -0
  117. package/docs/configuration-and-targets.md +812 -0
  118. package/docs/context-engine.md +236 -0
  119. package/docs/dispatch-architecture-rationale.md +126 -0
  120. package/docs/documentation-coverage.md +46 -0
  121. package/docs/documentation-guide.md +166 -0
  122. package/docs/environment-variables.md +105 -0
  123. package/docs/eval-runner.md +205 -0
  124. package/docs/evals-internal.md +298 -0
  125. package/docs/evidence-and-memory.md +243 -0
  126. package/docs/evolution.md +143 -0
  127. package/docs/exit-codes-and-output.md +74 -0
  128. package/docs/extensions-and-sharing.md +306 -0
  129. package/docs/fleet-demo-runbook.md +179 -0
  130. package/docs/fleet-dispatch.md +591 -0
  131. package/docs/glossary.md +75 -0
  132. package/docs/html/agents_blueprint.html +936 -0
  133. package/docs/html/alcf_blueprint.html +324 -0
  134. package/docs/html/architecture_blueprint.html +850 -0
  135. package/docs/html/commands_blueprint.html +794 -0
  136. package/docs/html/config_knobs_audit_blueprint.html +178 -0
  137. package/docs/html/configuration_blueprint.html +1080 -0
  138. package/docs/html/context_blueprint.html +603 -0
  139. package/docs/html/documentation_blueprint.html +832 -0
  140. package/docs/html/environment_blueprint.html +404 -0
  141. package/docs/html/eval_blueprint.html +743 -0
  142. package/docs/html/evals_internal_blueprint.html +190 -0
  143. package/docs/html/evolution_blueprint.html +674 -0
  144. package/docs/html/extensions_blueprint.html +2065 -0
  145. package/docs/html/fleet_dispatch_blueprint.html +286 -0
  146. package/docs/html/index.html +919 -0
  147. package/docs/html/lifecycle_blueprint.html +723 -0
  148. package/docs/html/memory_blueprint.html +699 -0
  149. package/docs/html/middleware_blueprint.html +664 -0
  150. package/docs/html/models_blueprint.html +2366 -0
  151. package/docs/html/observability_blueprint.html +683 -0
  152. package/docs/html/provider_adapter_blueprint.html +245 -0
  153. package/docs/html/safety_blueprint.html +1386 -0
  154. package/docs/html/shared.css +571 -0
  155. package/docs/html/shared.js +143 -0
  156. package/docs/html/skills_blueprint.html +671 -0
  157. package/docs/html/soak_blueprint.html +182 -0
  158. package/docs/html/tool_usage_blueprint.html +350 -0
  159. package/docs/html/tools_blueprint.html +2249 -0
  160. package/docs/html/trace_blueprint.html +235 -0
  161. package/docs/html/tui_design_blueprint.html +314 -0
  162. package/docs/html/validation_blueprint.html +961 -0
  163. package/docs/html/worker_dispatch_blueprint.html +231 -0
  164. package/docs/installation-and-lifecycle.md +308 -0
  165. package/docs/middleware-and-components.md +148 -0
  166. package/docs/model-catalog.md +189 -0
  167. package/docs/observability.md +233 -0
  168. package/docs/proactive-memory.md +452 -0
  169. package/docs/prompt-envelope-and-tools.md +142 -0
  170. package/docs/provider-adapter-cookbook.md +148 -0
  171. package/docs/release-cut-checklist.md +138 -0
  172. package/docs/safety-model.md +357 -0
  173. package/docs/scientific-validation.md +105 -0
  174. package/docs/session-lifecycle.md +156 -0
  175. package/docs/skills-marketplace.md +46 -0
  176. package/docs/tool-usage.md +527 -0
  177. package/docs/trace-store.md +132 -0
  178. package/docs/troubleshooting.md +33 -0
  179. package/docs/tui-design.md +239 -0
  180. package/docs/worker-dispatch-mechanics.md +242 -0
  181. package/package.json +132 -0
  182. package/skills/README.md +408 -0
  183. package/skills/git/commit-crafting/SKILL.md +79 -0
  184. package/skills/git/commit-crafting/evals.md +92 -0
  185. package/skills/git/create-pr/SKILL.md +116 -0
  186. package/skills/git/create-pr/evals.md +114 -0
  187. package/skills/git/investigate-issue/SKILL.md +139 -0
  188. package/skills/git/investigate-issue/evals.md +94 -0
  189. package/skills/git/resolve-merge-conflicts/SKILL.md +96 -0
  190. package/skills/git/resolve-merge-conflicts/evals.md +58 -0
  191. package/skills/git/review-changes/SKILL.md +103 -0
  192. package/skills/git/review-changes/evals.md +85 -0
  193. package/skills/git/worktree-create/SKILL.md +92 -0
  194. package/skills/git/worktree-create/evals.md +97 -0
  195. package/skills/git/worktree-create/references/worktree-setup.md +66 -0
  196. package/skills/git/worktree-merge/SKILL.md +95 -0
  197. package/skills/git/worktree-merge/evals.md +114 -0
  198. package/skills/skill-marketplace.json +261 -0
  199. package/skills/workflow/cut-it/SKILL.md +86 -0
  200. package/skills/workflow/cut-it/evals.md +42 -0
  201. package/src/domains/agents/builtins/architect.md +33 -0
  202. package/src/domains/agents/builtins/coder.md +31 -0
  203. package/src/domains/agents/builtins/context-bootstrap.md +38 -0
  204. package/src/domains/agents/builtins/debugger.md +30 -0
  205. package/src/domains/agents/builtins/documenter.md +31 -0
  206. package/src/domains/agents/builtins/git-master.md +30 -0
  207. package/src/domains/agents/builtins/provenance.md +30 -0
  208. package/src/domains/agents/builtins/researcher.md +71 -0
  209. package/src/domains/agents/builtins/scout.md +42 -0
  210. package/src/domains/agents/builtins/tester.md +31 -0
  211. package/src/domains/agents/builtins/verifier.md +30 -0
  212. package/src/domains/agents/builtins/wiki-writer.md +41 -0
  213. package/src/domains/agents/fleets/build-review.md +34 -0
  214. package/src/domains/agents/fleets/build-test.md +35 -0
  215. package/src/domains/agents/fleets/sdlc.md +86 -0
  216. package/src/domains/prompts/fragments/identity/clio-worker.md +11 -0
  217. package/src/domains/prompts/fragments/identity/clio.md +26 -0
  218. package/src/domains/prompts/fragments/operating/contract.md +64 -0
  219. package/src/domains/prompts/fragments/safety/auto-edit.md +14 -0
  220. package/src/domains/prompts/fragments/safety/full-auto.md +14 -0
  221. package/src/domains/prompts/fragments/safety/read-only.md +13 -0
  222. package/src/domains/prompts/fragments/safety/suggest.md +13 -0
  223. package/src/domains/prompts/fragments/wiki/page.md +75 -0
  224. package/src/domains/prompts/fragments/wiki/plan.md +48 -0
  225. package/src/domains/providers/models/cloud-models/alcf.yaml +40 -0
  226. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +993 -0
@@ -0,0 +1,977 @@
1
+ import "./chunk-NI4DEJMC.js";
2
+ import {
3
+ ensureClioState
4
+ } from "./chunk-7RBKDI66.js";
5
+ import {
6
+ ConfigDomainModule,
7
+ loadDomains
8
+ } from "./chunk-527KG6XR.js";
9
+ import "./chunk-UU3R62TT.js";
10
+ import "./chunk-HMYNFFY4.js";
11
+ import {
12
+ runConfigureCommand,
13
+ runTargetRemove,
14
+ runTargetRename
15
+ } from "./chunk-XNISANGE.js";
16
+ import "./chunk-KKKPTZLM.js";
17
+ import {
18
+ column,
19
+ terminalColumns,
20
+ truncate
21
+ } from "./chunk-ME6DNWIU.js";
22
+ import "./chunk-262G75JS.js";
23
+ import "./chunk-TFSSEXL6.js";
24
+ import "./chunk-PIDUD6M2.js";
25
+ import {
26
+ printError,
27
+ printOk
28
+ } from "./chunk-67MTHP2E.js";
29
+ import {
30
+ ProvidersDomainModule,
31
+ getRuntimeRegistry,
32
+ isDispatchEligibleRuntime,
33
+ isOrchestratorEligibleRuntime,
34
+ registerBuiltinRuntimes
35
+ } from "./chunk-TKHQ4DGZ.js";
36
+ import "./chunk-D5YD55AR.js";
37
+ import {
38
+ readSettings,
39
+ updateSettings
40
+ } from "./chunk-JWHCJDCI.js";
41
+ import {
42
+ THINKING_LEVELS
43
+ } from "./chunk-UHTSULZS.js";
44
+ import "./chunk-5LDRNKX2.js";
45
+ import "./chunk-UGYAX5YI.js";
46
+ import "./chunk-5N2FG33Q.js";
47
+ import "./chunk-VPAWTYLY.js";
48
+ import "./chunk-X3NE4WVW.js";
49
+ import "./chunk-DXQNI4PC.js";
50
+
51
+ // src/cli/targets.ts
52
+ import chalk from "chalk";
53
+ var HEADER = ["id", "tier", "runtime", "auth", "url", "model", "health", "caps", "notes"];
54
+ var HELP = `clio-coder targets
55
+
56
+ List and manage configured model targets.
57
+
58
+ Usage:
59
+ clio-coder targets [--json] [--probe] [--target <id>]
60
+ clio-coder targets add [configure flags]
61
+ clio-coder targets use <id> [--model <id>] [--orchestrator-model <id>] [--background-model <id>]
62
+ [--fleet-target <id>] [--fleet-model <id>]
63
+ clio-coder targets fleet [--json]
64
+ clio-coder targets profile list [--json]
65
+ clio-coder targets profile set <name> <id> [--model <id>] [--thinking <level>]
66
+ clio-coder targets profile <name> <id> [--model <id>] [--thinking <level>]
67
+ clio-coder targets profile remove <name> [--force]
68
+ clio-coder targets profile rename <old> <new>
69
+ clio-coder targets profile bind <agentId> <profileName>
70
+ clio-coder targets profile unbind <agentId>
71
+ clio-coder targets profile bindings [--json]
72
+ clio-coder targets convert <id> --runtime <runtimeId>
73
+ clio-coder targets remove <id>
74
+ clio-coder targets rename <old> <new>
75
+
76
+ Aliases:
77
+ --worker-target and --worker-model are accepted for --fleet-target and
78
+ --fleet-model, carried over from before the worker/fleet rename.
79
+ `;
80
+ var USE_USAGE = "clio-coder targets use <id> [--model <id>] [--orchestrator-model <id>] [--background-model <id>] [--fleet-target <id>] [--fleet-model <id>]";
81
+ function wantsHelp(args) {
82
+ return args.includes("--help") || args.includes("-h");
83
+ }
84
+ function printUsage(usage) {
85
+ process.stdout.write(`usage: ${usage}
86
+ `);
87
+ return 0;
88
+ }
89
+ var VALID_THINKING = new Set(THINKING_LEVELS);
90
+ var PROFILE_SUBCOMMANDS = /* @__PURE__ */ new Set(["list", "set", "remove", "rename", "bind", "unbind", "bindings"]);
91
+ function parseListArgs(args) {
92
+ const parsed = { json: false, probe: false, help: false };
93
+ for (let i = 0; i < args.length; i += 1) {
94
+ const arg = args[i];
95
+ if (arg === "--help" || arg === "-h") {
96
+ parsed.help = true;
97
+ continue;
98
+ }
99
+ if (arg === "--json") {
100
+ parsed.json = true;
101
+ continue;
102
+ }
103
+ if (arg === "--probe") {
104
+ parsed.probe = true;
105
+ continue;
106
+ }
107
+ if (arg === "--target") {
108
+ const value = args[i + 1];
109
+ if (!value) throw new Error("--target requires a value");
110
+ parsed.target = value;
111
+ i += 1;
112
+ continue;
113
+ }
114
+ if (arg?.startsWith("-")) throw new Error(`unknown flag: ${arg}`);
115
+ throw new Error(`unknown targets argument: ${arg}`);
116
+ }
117
+ return parsed;
118
+ }
119
+ async function runTargetsCommand(args) {
120
+ const subcommand = args[0];
121
+ if (subcommand === "add") return runConfigureCommand(args.slice(1));
122
+ if (subcommand === "use") return runUse(args.slice(1));
123
+ if (subcommand === "fleet" || subcommand === "workers") return runFleet(args.slice(1));
124
+ if (subcommand === "profile" || subcommand === "worker") return runProfile(args.slice(1));
125
+ if (subcommand === "remove") return runRemove(args.slice(1));
126
+ if (subcommand === "rename") return runRename(args.slice(1));
127
+ if (subcommand === "convert") return runConvert(args.slice(1));
128
+ if (subcommand === "--help" || subcommand === "-h") {
129
+ process.stdout.write(HELP);
130
+ return 0;
131
+ }
132
+ let parsed;
133
+ try {
134
+ parsed = parseListArgs(args);
135
+ } catch (error) {
136
+ printError(error instanceof Error ? error.message : String(error));
137
+ process.stderr.write(HELP);
138
+ return 2;
139
+ }
140
+ if (parsed.help) {
141
+ process.stdout.write(HELP);
142
+ return 0;
143
+ }
144
+ ensureClioState();
145
+ const loaded = await loadDomains([ConfigDomainModule, ProvidersDomainModule]);
146
+ const providers = loaded.getContract("providers");
147
+ if (!providers) {
148
+ process.stderr.write("targets: provider domain not loaded\n");
149
+ await loaded.stop();
150
+ return 1;
151
+ }
152
+ if (parsed.probe) {
153
+ try {
154
+ await providers.probeAllLive();
155
+ } catch (err) {
156
+ process.stderr.write(`targets: live probe failed: ${err instanceof Error ? err.message : String(err)}
157
+ `);
158
+ }
159
+ }
160
+ const entries = providers.list();
161
+ if (parsed.target !== void 0 && !entries.some((e) => e.target.id === parsed.target)) {
162
+ printError(
163
+ `no target with id ${parsed.target}. ${entries.length} target${entries.length === 1 ? "" : "s"} configured.`
164
+ );
165
+ await loaded.stop();
166
+ return 2;
167
+ }
168
+ const filtered = parsed.target ? entries.filter((e) => e.target.id === parsed.target) : entries;
169
+ if (parsed.json) {
170
+ const settings = readSettings();
171
+ const candidateFor = (status) => {
172
+ const orchestratorModel = settings.orchestrator?.target === status.target.id ? settings.orchestrator?.model ?? null : null;
173
+ return orchestratorModel ?? status.target.defaultModel ?? null;
174
+ };
175
+ const rows = filtered.map((status) => {
176
+ const candidate = candidateFor(status);
177
+ const detectedReasoning = candidate ? providers.getDetectedReasoning(status.target.id, candidate) : null;
178
+ return serializeStatus(status, { detectedReasoning, candidateModelId: candidate });
179
+ });
180
+ process.stdout.write(`${JSON.stringify({ targets: rows }, null, 2)}
181
+ `);
182
+ } else if (filtered.length === 0) {
183
+ process.stdout.write(
184
+ "no targets configured. run `clio-coder configure` or `clio-coder targets add` to register one.\n"
185
+ );
186
+ } else {
187
+ renderTable(providers, filtered);
188
+ }
189
+ await loaded.stop();
190
+ return 0;
191
+ }
192
+ function parseUseArgs(args) {
193
+ const id = args[0];
194
+ if (!id) return null;
195
+ const parsed = { id };
196
+ for (let i = 1; i < args.length; i += 1) {
197
+ const arg = args[i];
198
+ const need = () => {
199
+ const value = args[i + 1];
200
+ if (!value) throw new Error(`${arg} requires a value`);
201
+ i += 1;
202
+ return value;
203
+ };
204
+ if (arg === "--model") {
205
+ parsed.model = need();
206
+ continue;
207
+ }
208
+ if (arg === "--orchestrator-model") {
209
+ parsed.orchestratorModel = need();
210
+ continue;
211
+ }
212
+ if (arg === "--background-model") {
213
+ parsed.backgroundModel = need();
214
+ continue;
215
+ }
216
+ if (arg === "--fleet-model" || arg === "--worker-model") {
217
+ parsed.workerModel = need();
218
+ continue;
219
+ }
220
+ if (arg === "--fleet-target" || arg === "--worker-target") {
221
+ parsed.workerTarget = need();
222
+ continue;
223
+ }
224
+ if (arg?.startsWith("-")) throw new Error(`unknown flag: ${arg}`);
225
+ throw new Error(`unknown targets use argument: ${arg}`);
226
+ }
227
+ return parsed;
228
+ }
229
+ function runUse(args) {
230
+ if (wantsHelp(args)) return printUsage(USE_USAGE);
231
+ let parsed;
232
+ try {
233
+ parsed = parseUseArgs(args);
234
+ } catch (error) {
235
+ printError(error instanceof Error ? error.message : String(error));
236
+ return 2;
237
+ }
238
+ if (!parsed) {
239
+ printError(`usage: ${USE_USAGE}`);
240
+ return 2;
241
+ }
242
+ ensureClioState();
243
+ const settings = readSettings();
244
+ const target = settings.targets.find((entry) => entry.id === parsed.id);
245
+ if (!target) {
246
+ printError(`no target with id ${parsed.id}`);
247
+ return 1;
248
+ }
249
+ const registry = getRuntimeRegistry();
250
+ if (registry.list().length === 0) registerBuiltinRuntimes(registry);
251
+ const runtime = registry.get(target.runtime);
252
+ if (!runtime) {
253
+ printError(
254
+ `cannot use target '${target.id}' as orchestrator target because runtime '${target.runtime}' is not registered`
255
+ );
256
+ return 1;
257
+ }
258
+ if (!isOrchestratorEligibleRuntime(runtime)) {
259
+ printError(
260
+ `cannot use target '${target.id}' as orchestrator target because runtime '${runtime.id}' is not an HTTP/native runtime`
261
+ );
262
+ return 1;
263
+ }
264
+ let workerTarget = target;
265
+ if (parsed.workerTarget !== void 0 && parsed.workerTarget !== target.id) {
266
+ const resolved = resolveDispatchProfileTarget(settings, parsed.workerTarget, "fleet worker target");
267
+ if ("exitCode" in resolved) return resolved.exitCode;
268
+ workerTarget = resolved.target;
269
+ }
270
+ const sharedModel = parsed.model ?? target.defaultModel ?? null;
271
+ const orchestratorModel = parsed.orchestratorModel ?? sharedModel;
272
+ const workerModel = parsed.workerModel ?? (workerTarget === target ? sharedModel : workerTarget.defaultModel ?? null);
273
+ const backgroundModel = parsed.backgroundModel;
274
+ updateSettings((fresh) => {
275
+ fresh.orchestrator.target = target.id;
276
+ fresh.orchestrator.model = orchestratorModel;
277
+ fresh.workers.default.target = workerTarget.id;
278
+ fresh.workers.default.model = workerModel;
279
+ if (backgroundModel !== void 0) {
280
+ fresh.background.target = target.id;
281
+ fresh.background.model = backgroundModel;
282
+ }
283
+ });
284
+ const dispatchWhere = workerTarget === target ? "" : ` and ${workerTarget.id} for fleet dispatch`;
285
+ const chatWhere = workerTarget === target ? "for chat and fleet dispatch" : "for chat";
286
+ printOk(
287
+ `using target ${target.id} ${chatWhere}${dispatchWhere}${backgroundModel === void 0 ? "" : ", and background memory"}`
288
+ );
289
+ return 0;
290
+ }
291
+ function parseWorkerArgs(args) {
292
+ const name = args[0];
293
+ const targetId = args[1];
294
+ if (!name || !targetId) return null;
295
+ const parsed = { name, targetId };
296
+ for (let i = 2; i < args.length; i += 1) {
297
+ const arg = args[i];
298
+ const need = () => {
299
+ const value = args[i + 1];
300
+ if (!value) throw new Error(`${arg} requires a value`);
301
+ i += 1;
302
+ return value;
303
+ };
304
+ if (arg === "--model") {
305
+ parsed.model = need();
306
+ continue;
307
+ }
308
+ if (arg === "--thinking") {
309
+ const value = need();
310
+ if (!VALID_THINKING.has(value)) {
311
+ throw new Error("--thinking must be one of: off|minimal|low|medium|high|xhigh|max");
312
+ }
313
+ parsed.thinkingLevel = value;
314
+ continue;
315
+ }
316
+ if (arg?.startsWith("-")) throw new Error(`unknown flag: ${arg}`);
317
+ throw new Error(`unknown targets profile argument: ${arg}`);
318
+ }
319
+ return parsed;
320
+ }
321
+ function requireTrimmed(value, label) {
322
+ const trimmed = value?.trim() ?? "";
323
+ if (trimmed.length === 0) throw new Error(`${label} must be non-empty`);
324
+ return trimmed;
325
+ }
326
+ function parseProfileRemoveArgs(args) {
327
+ const name = args[0];
328
+ if (!name) return null;
329
+ const parsed = { name: name.trim(), force: false };
330
+ if (parsed.name.length === 0) throw new Error("profile name must be non-empty");
331
+ for (let i = 1; i < args.length; i += 1) {
332
+ const arg = args[i];
333
+ if (arg === "--force") {
334
+ parsed.force = true;
335
+ continue;
336
+ }
337
+ if (arg?.startsWith("-")) throw new Error(`unknown flag: ${arg}`);
338
+ throw new Error(`unknown targets profile remove argument: ${arg}`);
339
+ }
340
+ return parsed;
341
+ }
342
+ function parseProfileRenameArgs(args) {
343
+ if (args.length !== 2) return null;
344
+ const oldName = requireTrimmed(args[0], "old profile name");
345
+ const newName = requireTrimmed(args[1], "new profile name");
346
+ return { oldName, newName };
347
+ }
348
+ function parseProfileBindArgs(args) {
349
+ if (args.length !== 2) return null;
350
+ return {
351
+ agentId: requireTrimmed(args[0], "agent id"),
352
+ profileName: requireTrimmed(args[1], "profile name")
353
+ };
354
+ }
355
+ function resolveDispatchProfileTarget(settings, targetId, role = "fleet profile target") {
356
+ const target = settings.targets.find((entry) => entry.id === targetId);
357
+ if (!target) {
358
+ printError(`no target with id ${targetId}`);
359
+ return { exitCode: 2 };
360
+ }
361
+ const registry = getRuntimeRegistry();
362
+ if (registry.list().length === 0) registerBuiltinRuntimes(registry);
363
+ const runtime = registry.get(target.runtime);
364
+ if (!runtime) {
365
+ printError(`cannot use target '${target.id}' as ${role} because runtime '${target.runtime}' is not registered`);
366
+ return { exitCode: 1 };
367
+ }
368
+ if (!isDispatchEligibleRuntime(runtime)) {
369
+ printError(
370
+ `cannot use target '${target.id}' as ${role} because runtime '${runtime.id}' is not a fleet-dispatch target`
371
+ );
372
+ return { exitCode: 1 };
373
+ }
374
+ return { target };
375
+ }
376
+ function runProfileSet(args, usage = "clio-coder targets profile <name> <id> [--model <id>] [--thinking <level>]") {
377
+ if (wantsHelp(args)) return printUsage(usage);
378
+ let parsed;
379
+ try {
380
+ parsed = parseWorkerArgs(args);
381
+ } catch (error) {
382
+ printError(error instanceof Error ? error.message : String(error));
383
+ return 2;
384
+ }
385
+ if (!parsed) {
386
+ printError(`usage: ${usage}`);
387
+ return 2;
388
+ }
389
+ ensureClioState();
390
+ const settings = readSettings();
391
+ const resolved = resolveDispatchProfileTarget(settings, parsed.targetId);
392
+ if ("exitCode" in resolved) return resolved.exitCode;
393
+ const { target } = resolved;
394
+ const existing = settings.workers.profiles[parsed.name];
395
+ const profileName = parsed.name;
396
+ const profile = {
397
+ target: target.id,
398
+ model: parsed.model ?? target.defaultModel ?? null,
399
+ thinkingLevel: parsed.thinkingLevel ?? existing?.thinkingLevel ?? "off"
400
+ };
401
+ updateSettings((fresh) => {
402
+ fresh.workers.profiles[profileName] = profile;
403
+ });
404
+ printOk(`fleet profile ${parsed.name} -> ${target.id}`);
405
+ return 0;
406
+ }
407
+ function runProfileRemove(args) {
408
+ if (wantsHelp(args)) return printUsage("clio-coder targets profile remove <name> [--force]");
409
+ let parsed;
410
+ try {
411
+ parsed = parseProfileRemoveArgs(args);
412
+ } catch (error) {
413
+ printError(error instanceof Error ? error.message : String(error));
414
+ return 2;
415
+ }
416
+ if (!parsed) {
417
+ printError("usage: clio-coder targets profile remove <name> [--force]");
418
+ return 2;
419
+ }
420
+ ensureClioState();
421
+ const settings = readSettings();
422
+ if (!settings.workers.profiles[parsed.name]) {
423
+ printError(`no fleet profile named ${parsed.name}`);
424
+ return 1;
425
+ }
426
+ const boundAgents = Object.entries(settings.workers.agentBindings).filter(([, profileName]) => profileName === parsed.name).map(([agentId]) => agentId);
427
+ if (boundAgents.length > 0 && !parsed.force) {
428
+ printError(
429
+ `fleet profile ${parsed.name} is bound to ${boundAgents.length} agent${boundAgents.length === 1 ? "" : "s"}; use --force to remove profile and bindings`,
430
+ boundAgents.join(", ")
431
+ );
432
+ return 1;
433
+ }
434
+ let removedBindings = 0;
435
+ updateSettings((fresh) => {
436
+ delete fresh.workers.profiles[parsed.name];
437
+ for (const [agentId, profileName] of Object.entries(fresh.workers.agentBindings)) {
438
+ if (profileName !== parsed.name) continue;
439
+ delete fresh.workers.agentBindings[agentId];
440
+ removedBindings += 1;
441
+ }
442
+ });
443
+ printOk(
444
+ `removed fleet profile ${parsed.name} (${removedBindings} binding${removedBindings === 1 ? "" : "s"} removed)`
445
+ );
446
+ return 0;
447
+ }
448
+ function runProfileRename(args) {
449
+ if (wantsHelp(args)) return printUsage("clio-coder targets profile rename <old> <new>");
450
+ let parsed;
451
+ try {
452
+ parsed = parseProfileRenameArgs(args);
453
+ } catch (error) {
454
+ printError(error instanceof Error ? error.message : String(error));
455
+ return 2;
456
+ }
457
+ if (!parsed) {
458
+ printError("usage: clio-coder targets profile rename <old> <new>");
459
+ return 2;
460
+ }
461
+ if (parsed.oldName === parsed.newName) {
462
+ printError("old and new profile names are identical");
463
+ return 2;
464
+ }
465
+ ensureClioState();
466
+ const settings = readSettings();
467
+ if (!settings.workers.profiles[parsed.oldName]) {
468
+ printError(`no fleet profile named ${parsed.oldName}`);
469
+ return 1;
470
+ }
471
+ if (settings.workers.profiles[parsed.newName]) {
472
+ printError(`fleet profile already exists: ${parsed.newName}`);
473
+ return 2;
474
+ }
475
+ let updatedBindings = 0;
476
+ updateSettings((fresh) => {
477
+ const profile = fresh.workers.profiles[parsed.oldName];
478
+ if (!profile) return;
479
+ fresh.workers.profiles[parsed.newName] = profile;
480
+ delete fresh.workers.profiles[parsed.oldName];
481
+ for (const [agentId, profileName] of Object.entries(fresh.workers.agentBindings)) {
482
+ if (profileName !== parsed.oldName) continue;
483
+ fresh.workers.agentBindings[agentId] = parsed.newName;
484
+ updatedBindings += 1;
485
+ }
486
+ });
487
+ printOk(
488
+ `renamed fleet profile ${parsed.oldName} to ${parsed.newName} (${updatedBindings} binding${updatedBindings === 1 ? "" : "s"} updated)`
489
+ );
490
+ return 0;
491
+ }
492
+ function runProfileBind(args) {
493
+ if (wantsHelp(args)) return printUsage("clio-coder targets profile bind <agentId> <profileName>");
494
+ let parsed;
495
+ try {
496
+ parsed = parseProfileBindArgs(args);
497
+ } catch (error) {
498
+ printError(error instanceof Error ? error.message : String(error));
499
+ return 2;
500
+ }
501
+ if (!parsed) {
502
+ printError("usage: clio-coder targets profile bind <agentId> <profileName>");
503
+ return 2;
504
+ }
505
+ ensureClioState();
506
+ const settings = readSettings();
507
+ if (settings.delegation.agents.some((agent) => agent.id === parsed.agentId)) {
508
+ printError(
509
+ `cannot bind ACP delegation agent '${parsed.agentId}' to a fleet profile; ACP agents use their own runner and ignore native target routing`
510
+ );
511
+ return 1;
512
+ }
513
+ if (!settings.workers.profiles[parsed.profileName]) {
514
+ process.stderr.write(
515
+ `${chalk.yellow("warning:")} fleet profile '${parsed.profileName}' is not configured; binding will resolve after the profile exists
516
+ `
517
+ );
518
+ }
519
+ updateSettings((fresh) => {
520
+ fresh.workers.agentBindings[parsed.agentId] = parsed.profileName;
521
+ });
522
+ printOk(`bound agent ${parsed.agentId} -> fleet profile ${parsed.profileName}`);
523
+ return 0;
524
+ }
525
+ function runProfileUnbind(args) {
526
+ if (wantsHelp(args)) return printUsage("clio-coder targets profile unbind <agentId>");
527
+ let parsed;
528
+ try {
529
+ if (args.length !== 1) throw new Error("usage: clio-coder targets profile unbind <agentId>");
530
+ parsed = requireTrimmed(args[0], "agent id");
531
+ } catch (error) {
532
+ printError(error instanceof Error ? error.message : String(error));
533
+ return 2;
534
+ }
535
+ ensureClioState();
536
+ const settings = readSettings();
537
+ if (!settings.workers.agentBindings[parsed]) {
538
+ printError(`agent ${parsed} is not bound to a fleet profile`);
539
+ return 1;
540
+ }
541
+ updateSettings((fresh) => {
542
+ delete fresh.workers.agentBindings[parsed];
543
+ });
544
+ printOk(`unbound agent ${parsed}`);
545
+ return 0;
546
+ }
547
+ function runProfileBindings(args) {
548
+ let json = false;
549
+ for (const arg of args) {
550
+ if (arg === "--json") {
551
+ json = true;
552
+ continue;
553
+ }
554
+ if (arg === "--help" || arg === "-h") {
555
+ process.stdout.write("usage: clio-coder targets profile bindings [--json]\n");
556
+ return 0;
557
+ }
558
+ printError(`unknown targets profile bindings argument: ${arg}`);
559
+ return 2;
560
+ }
561
+ ensureClioState();
562
+ const settings = readSettings();
563
+ const rows = Object.entries(settings.workers.agentBindings).sort(([a], [b]) => a.localeCompare(b)).map(([agentId, profileName]) => {
564
+ const profile = settings.workers.profiles[profileName];
565
+ return {
566
+ agentId,
567
+ profile: profileName,
568
+ target: profile?.target ?? null,
569
+ model: profile?.model ?? null,
570
+ warning: profile ? null : "missing profile"
571
+ };
572
+ });
573
+ if (json) {
574
+ process.stdout.write(`${JSON.stringify(rows, null, 2)}
575
+ `);
576
+ return 0;
577
+ }
578
+ if (rows.length === 0) {
579
+ process.stdout.write(
580
+ "no agent profile bindings configured. run `clio-coder targets profile bind <agentId> <profile>` to add one.\n"
581
+ );
582
+ return 0;
583
+ }
584
+ process.stdout.write(
585
+ `${column("agent", 18)}${column("profile", 20)}${column("target", 16)}${column("model", 30)}warning
586
+ `
587
+ );
588
+ for (const row of rows) {
589
+ process.stdout.write(
590
+ `${column(row.agentId, 18)}${column(row.profile, 20)}${column(row.target ?? "-", 16)}${column(row.model ?? "-", 30)}${row.warning ?? "-"}
591
+ `
592
+ );
593
+ }
594
+ return 0;
595
+ }
596
+ function runProfile(args) {
597
+ const subcommand = args[0];
598
+ if (subcommand && PROFILE_SUBCOMMANDS.has(subcommand)) {
599
+ switch (subcommand) {
600
+ case "list":
601
+ return runFleet(args.slice(1), "clio-coder targets profile list [--json]");
602
+ case "set":
603
+ return runProfileSet(
604
+ args.slice(1),
605
+ "clio-coder targets profile set <name> <id> [--model <id>] [--thinking <level>]"
606
+ );
607
+ case "remove":
608
+ return runProfileRemove(args.slice(1));
609
+ case "rename":
610
+ return runProfileRename(args.slice(1));
611
+ case "bind":
612
+ return runProfileBind(args.slice(1));
613
+ case "unbind":
614
+ return runProfileUnbind(args.slice(1));
615
+ case "bindings":
616
+ return runProfileBindings(args.slice(1));
617
+ }
618
+ }
619
+ return runProfileSet(args);
620
+ }
621
+ function runFleet(args, usage = "clio-coder targets fleet [--json]") {
622
+ let json = false;
623
+ for (const arg of args) {
624
+ if (arg === "--json") {
625
+ json = true;
626
+ continue;
627
+ }
628
+ if (arg === "--help" || arg === "-h") {
629
+ process.stdout.write(`usage: ${usage}
630
+ `);
631
+ return 0;
632
+ }
633
+ printError(`unknown targets fleet argument: ${arg}`);
634
+ return 2;
635
+ }
636
+ ensureClioState();
637
+ const settings = readSettings();
638
+ const byId = new Map(settings.targets.map((target) => [target.id, target]));
639
+ const rows = Object.entries(settings.workers.profiles).map(([name, profile]) => {
640
+ const target = profile.target ? byId.get(profile.target) : void 0;
641
+ return {
642
+ name,
643
+ target: profile.target,
644
+ runtime: target?.runtime ?? null,
645
+ model: profile.model,
646
+ thinkingLevel: profile.thinkingLevel
647
+ };
648
+ });
649
+ if (json) {
650
+ process.stdout.write(`${JSON.stringify(rows, null, 2)}
651
+ `);
652
+ return 0;
653
+ }
654
+ if (rows.length === 0) {
655
+ process.stdout.write("no fleet profiles configured. run `clio-coder targets profile <name> <id>` to add one.\n");
656
+ return 0;
657
+ }
658
+ process.stdout.write(
659
+ `${column("profile", 18)}${column("target", 16)}${column("runtime", 20)}${column("model", 30)}thinking
660
+ `
661
+ );
662
+ for (const row of rows) {
663
+ process.stdout.write(
664
+ `${column(row.name, 18)}${column(row.target ?? "-", 16)}${column(row.runtime ?? "-", 20)}${column(row.model ?? "-", 30)}${row.thinkingLevel}
665
+ `
666
+ );
667
+ }
668
+ return 0;
669
+ }
670
+ function runRemove(args) {
671
+ if (wantsHelp(args)) return printUsage("clio-coder targets remove <id>");
672
+ if (args.length !== 1 || !args[0]) {
673
+ printError("usage: clio-coder targets remove <id>");
674
+ return 2;
675
+ }
676
+ ensureClioState();
677
+ return runTargetRemove(args[0]);
678
+ }
679
+ function runRename(args) {
680
+ if (wantsHelp(args)) return printUsage("clio-coder targets rename <old> <new>");
681
+ if (args.length !== 2 || !args[0] || !args[1]) {
682
+ printError("usage: clio-coder targets rename <old> <new>");
683
+ return 2;
684
+ }
685
+ ensureClioState();
686
+ return runTargetRename(args[0], args[1]);
687
+ }
688
+ var CONVERT_USAGE = "clio-coder targets convert <id> --runtime <runtimeId>";
689
+ function runConvert(args) {
690
+ if (wantsHelp(args)) return printUsage(CONVERT_USAGE);
691
+ const id = args[0];
692
+ if (!id || id.startsWith("-")) {
693
+ printError(`usage: ${CONVERT_USAGE}`);
694
+ return 2;
695
+ }
696
+ let runtimeId;
697
+ for (let i = 1; i < args.length; i += 1) {
698
+ const arg = args[i];
699
+ if (arg === "--runtime") {
700
+ const value = args[i + 1];
701
+ if (!value) {
702
+ printError("--runtime requires a value");
703
+ return 2;
704
+ }
705
+ runtimeId = value;
706
+ i += 1;
707
+ continue;
708
+ }
709
+ printError(`unknown convert argument: ${arg}`);
710
+ return 2;
711
+ }
712
+ if (!runtimeId) {
713
+ printError("--runtime is required");
714
+ return 2;
715
+ }
716
+ ensureClioState();
717
+ const registry = getRuntimeRegistry();
718
+ if (registry.list().length === 0) registerBuiltinRuntimes(registry);
719
+ const runtime = registry.get(runtimeId);
720
+ if (!runtime) {
721
+ printError(`unknown runtime id: ${runtimeId} (run \`clio-coder configure --list\` to see registered runtimes)`);
722
+ return 2;
723
+ }
724
+ const settings = readSettings();
725
+ const target = settings.targets.find((entry) => entry.id === id);
726
+ if (!target) {
727
+ printError(`no target with id ${id}`);
728
+ return 1;
729
+ }
730
+ if (target.runtime === runtimeId) {
731
+ printOk(`target ${id} already uses runtime ${runtimeId}`);
732
+ return 0;
733
+ }
734
+ if (settings.orchestrator.target === id && !isOrchestratorEligibleRuntime(runtime)) {
735
+ printError(`cannot convert orchestrator target '${id}' to non-HTTP/native runtime '${runtime.id}'`);
736
+ return 1;
737
+ }
738
+ const previousRuntime = target.runtime;
739
+ updateSettings((fresh) => {
740
+ const entry = fresh.targets.find((candidate) => candidate.id === id);
741
+ if (entry) entry.runtime = runtimeId;
742
+ });
743
+ printOk(`converted target ${id}: ${previousRuntime} -> ${runtimeId}`);
744
+ return 0;
745
+ }
746
+ var TABLE_COLUMNS = [
747
+ "id",
748
+ "tier",
749
+ "runtime",
750
+ "auth",
751
+ "url",
752
+ "model",
753
+ "health",
754
+ "caps",
755
+ "notes"
756
+ ];
757
+ var TABLE_GAP = 1;
758
+ var TABLE_SHRINK_ORDER = [
759
+ ["notes", 16],
760
+ ["url", 12],
761
+ ["model", 12],
762
+ ["notes", 0],
763
+ ["auth", 6],
764
+ ["runtime", 6],
765
+ ["tier", 4]
766
+ ];
767
+ var TABLE_GROW_ORDER = [
768
+ ["url", Number.POSITIVE_INFINITY],
769
+ ["model", Number.POSITIVE_INFINITY],
770
+ ["notes", 16],
771
+ ["auth", Number.POSITIVE_INFINITY],
772
+ ["runtime", Number.POSITIVE_INFINITY],
773
+ ["tier", Number.POSITIVE_INFINITY],
774
+ ["notes", Number.POSITIVE_INFINITY]
775
+ ];
776
+ function tableWidths(rows, width) {
777
+ const natural = {};
778
+ for (const [index, key] of TABLE_COLUMNS.entries()) {
779
+ natural[key] = rows.reduce((widest, row) => Math.max(widest, row[key].length), (HEADER[index] ?? key).length);
780
+ }
781
+ const widths = { ...natural };
782
+ for (const [key, floor] of TABLE_SHRINK_ORDER) widths[key] = Math.min(widths[key], floor);
783
+ const total = () => TABLE_COLUMNS.reduce((sum, key) => sum + widths[key], 0) + TABLE_GAP * (TABLE_COLUMNS.length - 1);
784
+ let surplus = width - total();
785
+ for (const [key, ceiling] of TABLE_GROW_ORDER) {
786
+ if (surplus <= 0) break;
787
+ const take = Math.min(surplus, Math.max(0, Math.min(natural[key], ceiling) - widths[key]));
788
+ widths[key] += take;
789
+ surplus -= take;
790
+ }
791
+ return widths;
792
+ }
793
+ function formatTargetTable(rows, width, paintHealth = (cell) => cell) {
794
+ const widths = tableWidths(rows, width);
795
+ const line = (cells) => cells.join(" ".repeat(TABLE_GAP)).trimEnd();
796
+ return {
797
+ header: truncate(line(TABLE_COLUMNS.map((key, index) => column(HEADER[index] ?? key, widths[key]))), width),
798
+ rows: rows.map((row) => {
799
+ const cells = TABLE_COLUMNS.map((key) => column(row[key], widths[key]));
800
+ const plain = line(cells);
801
+ if (plain.length > width) return truncate(plain, width);
802
+ return line(cells.map((cell, index) => TABLE_COLUMNS[index] === "health" ? paintHealth(cell, row) : cell));
803
+ })
804
+ };
805
+ }
806
+ function renderTable(providers, entries) {
807
+ const sorted = [...entries].sort(compareStatusByTier);
808
+ const table = formatTargetTable(
809
+ sorted.map((status) => targetTableRow(providers, status)),
810
+ terminalColumns(),
811
+ // The cell is padded before it is painted, so the ansi bytes land outside
812
+ // the width arithmetic instead of having to be guessed at with slack.
813
+ (cell, row) => healthColor(row.health)(cell)
814
+ );
815
+ let currentTier = null;
816
+ for (const [index, status] of sorted.entries()) {
817
+ const tier = statusTier(status);
818
+ if (tier !== currentTier) {
819
+ currentTier = tier;
820
+ process.stdout.write(`${chalk.bold(tierLabel(tier))}
821
+ `);
822
+ process.stdout.write(`${chalk.bold(table.header)}
823
+ `);
824
+ }
825
+ process.stdout.write(`${table.rows[index] ?? ""}
826
+ `);
827
+ }
828
+ }
829
+ function targetTableRow(providers, status) {
830
+ return {
831
+ id: status.target.id,
832
+ tier: statusTier(status),
833
+ runtime: status.runtime ? status.runtime.id : status.target.runtime,
834
+ auth: formatAuth(providers, status),
835
+ url: formatUrl(status),
836
+ model: status.target.defaultModel ?? "-",
837
+ health: status.health.status,
838
+ caps: capabilityBadges(status.capabilities),
839
+ notes: formatNotes(status)
840
+ };
841
+ }
842
+ function healthColor(status) {
843
+ switch (status) {
844
+ case "healthy":
845
+ return chalk.green;
846
+ case "degraded":
847
+ return chalk.yellow;
848
+ case "down":
849
+ return chalk.red;
850
+ default:
851
+ return chalk.dim;
852
+ }
853
+ }
854
+ function formatUrl(status) {
855
+ if (status.target.url) return status.target.url;
856
+ return "(built-in)";
857
+ }
858
+ function formatAuth(providers, status) {
859
+ if (!status.runtime) return "-";
860
+ if (status.runtime.auth !== "api-key" && status.runtime.auth !== "oauth") return status.runtime.auth;
861
+ const auth = providers.auth.statusForTarget(status.target, status.runtime);
862
+ if (!auth.available) return "disconnected";
863
+ if (auth.source === "environment") return auth.detail ? `env:${auth.detail}` : "environment";
864
+ return auth.source.replace("stored-", "");
865
+ }
866
+ function capabilityBadges(caps) {
867
+ const badge = (on, letter) => on ? letter : "-";
868
+ return [
869
+ badge(caps.chat, "C"),
870
+ badge(caps.tools, "T"),
871
+ badge(caps.reasoning, "R"),
872
+ badge(caps.vision, "V"),
873
+ badge(caps.embeddings, "E"),
874
+ badge(caps.rerank, "K"),
875
+ badge(caps.fim, "F")
876
+ ].join("");
877
+ }
878
+ function residentModelsSummary(states) {
879
+ if (!states) return null;
880
+ const entries = Object.entries(states);
881
+ if (entries.length === 0) return null;
882
+ const resident = entries.filter(([, status]) => status.state === "loaded" || status.state === "loading").map(([id, status]) => status.state === "loading" ? `${id} (loading)` : id);
883
+ return resident.length > 0 ? `resident: ${resident.join(", ")}` : "resident: none";
884
+ }
885
+ function formatContextWindow(status) {
886
+ const window = status.capabilities.contextWindow;
887
+ return status.contextWindowProvenance === "runtime-default" ? `ctx ${window} (unverified runtime default)` : `ctx ${window}`;
888
+ }
889
+ function formatNotes(status) {
890
+ const parts = [];
891
+ if (status.target.gateway) parts.push("gateway");
892
+ if (status.runtime?.auth === "oauth") parts.push("oauth");
893
+ if (status.runtime?.auth === "claude-cli") parts.push("claude-cli");
894
+ if (status.capabilities.contextWindow > 0) parts.push(formatContextWindow(status));
895
+ if (!status.available && status.reason) parts.push(status.reason);
896
+ const residency = residentModelsSummary(status.discoveredModelStates);
897
+ if (residency) parts.push(residency);
898
+ if (status.probeNotes && status.probeNotes.length > 0) parts.push(`note: ${status.probeNotes.join("; ")}`);
899
+ return parts.join(" ");
900
+ }
901
+ function statusTier(status) {
902
+ return status.runtime?.tier ?? "unknown";
903
+ }
904
+ function tierLabel(tier) {
905
+ switch (tier) {
906
+ case "protocol":
907
+ return "Protocol";
908
+ case "cloud":
909
+ return "Cloud";
910
+ case "subscription":
911
+ return "Subscription";
912
+ case "local-native":
913
+ return "Local native";
914
+ case "unknown":
915
+ return "Unknown";
916
+ }
917
+ }
918
+ function tierRank(tier) {
919
+ switch (tier) {
920
+ case "protocol":
921
+ return 0;
922
+ case "cloud":
923
+ return 1;
924
+ case "subscription":
925
+ return 2;
926
+ case "local-native":
927
+ return 3;
928
+ case "unknown":
929
+ return 4;
930
+ }
931
+ }
932
+ function compareStatusByTier(a, b) {
933
+ return tierRank(statusTier(a)) - tierRank(statusTier(b)) || a.target.id.localeCompare(b.target.id) || a.target.runtime.localeCompare(b.target.runtime);
934
+ }
935
+ function serializeStatus(status, extras = {
936
+ detectedReasoning: null,
937
+ candidateModelId: null
938
+ }) {
939
+ const out = {
940
+ target: status.target,
941
+ runtime: status.runtime,
942
+ available: status.available,
943
+ reason: status.reason,
944
+ health: status.health,
945
+ capabilities: status.capabilities,
946
+ discoveredModels: status.discoveredModels,
947
+ tier: statusTier(status),
948
+ detectedReasoning: extras.detectedReasoning,
949
+ reasoningCandidateModelId: extras.candidateModelId
950
+ };
951
+ if (status.contextWindowProvenance !== void 0) {
952
+ out.contextWindowProvenance = status.contextWindowProvenance;
953
+ }
954
+ if (status.discoveredModelsSource !== void 0) {
955
+ out.discoveredModelsSource = status.discoveredModelsSource;
956
+ }
957
+ if (status.discoveredModelStates !== void 0) {
958
+ out.discoveredModelStates = status.discoveredModelStates;
959
+ }
960
+ if (status.probeCapabilities !== void 0) {
961
+ out.probeCapabilities = status.probeCapabilities;
962
+ }
963
+ if (status.probeModelId !== void 0) {
964
+ out.probeModelId = status.probeModelId;
965
+ }
966
+ if (status.probeNotes !== void 0) {
967
+ out.probeNotes = status.probeNotes;
968
+ }
969
+ return out;
970
+ }
971
+ export {
972
+ formatContextWindow,
973
+ formatTargetTable,
974
+ residentModelsSummary,
975
+ runTargetsCommand
976
+ };
977
+ //# sourceMappingURL=targets-DZMEZAH4.js.map