@iowarp/clio-coder 0.3.4 → 0.3.6

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 (265) hide show
  1. package/CHANGELOG.md +37 -2
  2. package/CONTRIBUTING.md +6 -6
  3. package/README.md +2 -2
  4. package/dist/{acp-S5R4RR5B.js → acp-2BEHC4DL.js} +4 -4
  5. package/dist/{agents-P6DMMVZY.js → agents-LNNFTM53.js} +13 -11
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-2XCZLPKS.js → auth-KXXFI2VS.js} +6 -6
  8. package/dist/{chunk-YCWGATWI.js → chunk-24I7BN55.js} +2 -2
  9. package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
  10. package/dist/chunk-3BPUFZDL.js +37 -0
  11. package/dist/{chunk-WPQLXFOZ.js → chunk-43AOLP7E.js} +2 -2
  12. package/dist/{chunk-N4CZJQRK.js → chunk-5JGRAMKL.js} +4 -4
  13. package/dist/{chunk-BRXQQJFP.js → chunk-6US73PDB.js} +568 -47
  14. package/dist/{chunk-K6WL7QZT.js → chunk-6XXKFVSN.js} +2 -2
  15. package/dist/{chunk-QQK64KLB.js → chunk-CJUB2JJ2.js} +138 -20
  16. package/dist/{chunk-HV5X7OR2.js → chunk-CKXWIANG.js} +12 -12
  17. package/dist/{chunk-UZHIZC5S.js → chunk-CYQKWTG3.js} +61 -76
  18. package/dist/{chunk-QWU7ZBO7.js → chunk-DJVECN66.js} +204 -45
  19. package/dist/{chunk-ZWMF7253.js → chunk-E2ER4LJF.js} +304 -9
  20. package/dist/{chunk-7RXG6QRZ.js → chunk-EKY57CSP.js} +2 -75
  21. package/dist/{chunk-EDRHSCIE.js → chunk-EYPA3EGJ.js} +10 -2
  22. package/dist/{chunk-TTNYS3EA.js → chunk-G7MUEIGA.js} +1 -1
  23. package/dist/{chunk-BPGS2WCQ.js → chunk-GEYXPTRF.js} +2 -1
  24. package/dist/{chunk-BEY543CS.js → chunk-GOXNB3AO.js} +5 -2
  25. package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
  26. package/dist/chunk-HWUFFB6L.js +83 -0
  27. package/dist/{chunk-35MKKU5R.js → chunk-K7T3E2SR.js} +15 -8
  28. package/dist/{chunk-VAWWTKDP.js → chunk-KHSFENX2.js} +2 -2
  29. package/dist/chunk-LCGCVYZ4.js +57 -0
  30. package/dist/{chunk-X6COSD2O.js → chunk-LYF7OHWH.js} +41 -14
  31. package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
  32. package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
  33. package/dist/{chunk-5M54SPOL.js → chunk-ODFEOB4F.js} +161 -5
  34. package/dist/{chunk-3JLKSKD7.js → chunk-OH3TOQTB.js} +5 -1
  35. package/dist/{chunk-MEQ45TQ4.js → chunk-PBTHKCPN.js} +18 -4
  36. package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
  37. package/dist/{chunk-QQL5RT5M.js → chunk-QM3F2GKX.js} +94 -36
  38. package/dist/{chunk-A2GZF7DC.js → chunk-QNQHSOLF.js} +4 -4
  39. package/dist/{chunk-KRPY7NTG.js → chunk-R46L2BIR.js} +3 -3
  40. package/dist/{chunk-BP4OYD6A.js → chunk-RY3LY4J5.js} +20 -2
  41. package/dist/{chunk-34475P3I.js → chunk-TSHXZTOQ.js} +5 -4
  42. package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
  43. package/dist/{chunk-2TZWSW76.js → chunk-WHGPSPT5.js} +2 -2
  44. package/dist/{chunk-TW3WDMVS.js → chunk-WHJYKASB.js} +2 -2
  45. package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
  46. package/dist/{chunk-HXG4IURW.js → chunk-XE2VEJHX.js} +2 -2
  47. package/dist/{chunk-3HZ5RWN2.js → chunk-XF5N4U5A.js} +7 -6
  48. package/dist/{chunk-ZYKPLLNQ.js → chunk-XXQNGV4M.js} +590 -32
  49. package/dist/{chunk-4JUF2NNX.js → chunk-XYDYPRZI.js} +4 -4
  50. package/dist/{chunk-VMNQ6OZA.js → chunk-ZRGEBJ4T.js} +971 -794
  51. package/dist/{chunk-2LZI5CAG.js → chunk-ZXF4XRKW.js} +75 -33
  52. package/dist/{chunk-VSNATDE6.js → chunk-ZZMN5OM4.js} +2 -2
  53. package/dist/cli/index.js +31 -31
  54. package/dist/{clio-J5JIOIDS.js → clio-M2KGYUFZ.js} +2 -2
  55. package/dist/{code-nav-AXCXSBHX.js → code-nav-GQNL7XA6.js} +5 -5
  56. package/dist/codewiki/build-worker.js +4 -4
  57. package/dist/{components-KELWS457.js → components-5TTYYX6G.js} +3 -3
  58. package/dist/{config-OEBMIN2U.js → config-XUUYQIWO.js} +27 -25
  59. package/dist/{configure-PUQOSIXQ.js → configure-IHJ7YOMV.js} +7 -7
  60. package/dist/{context-URSXPBCK.js → context-74JLXAWD.js} +12 -12
  61. package/dist/{context-MGSE4Z2T.js → context-75MIWW3U.js} +24 -22
  62. package/dist/{context-EKDCKUUZ.js → context-ZQ7SIFJV.js} +8 -7
  63. package/dist/{context-clear-KDAJRNUK.js → context-clear-GYKWNUML.js} +24 -22
  64. package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
  65. package/dist/{context-working-set-SBKMPPI2.js → context-working-set-UX5KEP4J.js} +11 -10
  66. package/dist/{dispatch-runner-MSWN72NK.js → dispatch-runner-GIJBHNFL.js} +21 -20
  67. package/dist/{docs-2C2LTVT2.js → docs-6FZSCG5B.js} +3 -3
  68. package/dist/{doctor-7BSE27PJ.js → doctor-SVJ5BZCW.js} +4 -4
  69. package/dist/{eval-IZGDOO4H.js → eval-CG6LLBLD.js} +47 -232
  70. package/dist/{evidence-SR7WXB5B.js → evidence-ZYFIEN42.js} +19 -18
  71. package/dist/{evolve-K7VE2CBX.js → evolve-QGEXEMDW.js} +19 -18
  72. package/dist/{extensions-QVDOHDGJ.js → extensions-ADGNCJJD.js} +3 -3
  73. package/dist/{fleet-7XMJNQNF.js → fleet-S5R4ZOQY.js} +49 -30
  74. package/dist/{fleet-preflight-AQNAH644.js → fleet-preflight-BHSNPBMH.js} +2 -2
  75. package/dist/{init-JGNPAYXT.js → init-5DRU55YR.js} +31 -29
  76. package/dist/memory-7YKKR6UC.js +467 -0
  77. package/dist/{models-ZMMLFJNN.js → models-ZPOLRU2C.js} +10 -10
  78. package/dist/{monitor-2F3T5KHP.js → monitor-US5F5YGZ.js} +33 -18
  79. package/dist/{orchestrator-ORHT43JB.js → orchestrator-E2AL4T5N.js} +1092 -659
  80. package/dist/{paths-UXLN5YYZ.js → paths-E7KYAQWE.js} +3 -3
  81. package/dist/{reset-NXGTYNUO.js → reset-KZ652EK6.js} +3 -3
  82. package/dist/{run-RF4WJGMT.js → run-SRNBKDWD.js} +52 -40
  83. package/dist/{share-UT3W6E4M.js → share-CGZE33UP.js} +3 -3
  84. package/dist/{skills-PSACKC5Q.js → skills-S2X4DLY5.js} +4 -4
  85. package/dist/{skills-eval-WJSI55RZ.js → skills-eval-W2GGIC4R.js} +19 -18
  86. package/dist/{targets-PIIRAOYS.js → targets-54SWINWB.js} +14 -12
  87. package/dist/{terminal-lease-ULWXWNVY.js → terminal-lease-SAIF2OGY.js} +5 -4
  88. package/dist/{uninstall-FZCQCDKC.js → uninstall-BVLWXKBT.js} +3 -3
  89. package/dist/{upgrade-346TZ6AV.js → upgrade-JKAR27XC.js} +8 -8
  90. package/dist/{usage-6KKXR32N.js → usage-MSAWCLX4.js} +60 -27
  91. package/dist/{verifiers-4UUM6TEE.js → verifiers-NCBTHHN2.js} +60 -54
  92. package/dist/{wiki-generate-7STOCIFZ.js → wiki-generate-GUSOQ6ZP.js} +30 -28
  93. package/dist/worker/entry.js +69 -58
  94. package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
  95. package/docs/README.md +3 -3
  96. package/docs/acp.md +1 -1
  97. package/docs/alcf-provider.md +1 -1
  98. package/docs/architecture.md +2 -2
  99. package/docs/artifact-placement.md +1 -2
  100. package/docs/artifact-versions.md +1 -1
  101. package/docs/built-in-agents.md +1 -1
  102. package/docs/capacity-and-scheduling.md +1 -1
  103. package/docs/commands-and-modes.md +9 -7
  104. package/docs/configuration-and-targets.md +12 -1
  105. package/docs/context-engine.md +4 -2
  106. package/docs/context-working-set.md +4 -4
  107. package/docs/development-pipeline.md +1 -1
  108. package/docs/documentation-coverage.md +3 -3
  109. package/docs/documentation-guide.md +2 -2
  110. package/docs/eval-runner.md +1 -1
  111. package/docs/evals-internal.md +4 -45
  112. package/docs/evidence-and-memory.md +67 -7
  113. package/docs/evolution.md +1 -1
  114. package/docs/exit-codes-and-output.md +1 -1
  115. package/docs/extensions-and-sharing.md +2 -2
  116. package/docs/fleet-dispatch.md +28 -2
  117. package/docs/installation-and-lifecycle.md +2 -2
  118. package/docs/middleware-and-components.md +19 -2
  119. package/docs/model-catalog.md +1 -1
  120. package/docs/observability.md +3 -3
  121. package/docs/proactive-memory.md +26 -16
  122. package/docs/prompt-envelope-and-tools.md +4 -2
  123. package/docs/provider-adapter-cookbook.md +1 -1
  124. package/docs/release-cut-checklist.md +38 -35
  125. package/docs/safety-model.md +29 -7
  126. package/docs/scientific-validation.md +3 -3
  127. package/docs/session-lifecycle.md +1 -1
  128. package/docs/skills-marketplace.md +1 -1
  129. package/docs/tool-usage.md +2 -2
  130. package/docs/trace-store.md +1 -1
  131. package/docs/troubleshooting.md +1 -1
  132. package/docs/tui-design.md +38 -4
  133. package/docs/worker-dispatch-mechanics.md +1 -1
  134. package/package.json +7 -4
  135. package/src/cli/agents.ts +2 -3
  136. package/src/cli/argv.ts +14 -1
  137. package/src/cli/fleet.ts +15 -0
  138. package/src/cli/index.ts +1 -1
  139. package/src/cli/memory.ts +272 -10
  140. package/src/cli/modes/json-stream.ts +2 -2
  141. package/src/cli/modes/print.ts +12 -1
  142. package/src/cli/run.ts +22 -2
  143. package/src/cli/targets.ts +12 -3
  144. package/src/cli/usage.ts +55 -7
  145. package/src/core/bus-events.ts +3 -0
  146. package/src/core/response-model-id.ts +134 -0
  147. package/src/core/toml.ts +62 -0
  148. package/src/core/workspace-files.ts +0 -1
  149. package/src/domains/agents/builtins/architect.md +1 -1
  150. package/src/domains/agents/catalog.ts +5 -4
  151. package/src/domains/agents/recipe.ts +54 -14
  152. package/src/domains/agents/result-contract.ts +7 -4
  153. package/src/domains/context/bootstrap.ts +36 -27
  154. package/src/domains/context/project-metadata.ts +19 -63
  155. package/src/domains/context/prompt-context.ts +8 -0
  156. package/src/domains/context/working-set/policies/index.ts +3 -4
  157. package/src/domains/dispatch/budget-envelope.ts +396 -0
  158. package/src/domains/dispatch/contract.ts +2 -0
  159. package/src/domains/dispatch/extension.ts +81 -27
  160. package/src/domains/dispatch/orphan-recovery.ts +1 -0
  161. package/src/domains/dispatch/receipt-integrity.ts +4 -0
  162. package/src/domains/dispatch/state.ts +1 -0
  163. package/src/domains/dispatch/types.ts +10 -3
  164. package/src/domains/dispatch/validation.ts +14 -0
  165. package/src/domains/dispatch/worker-spawn.ts +14 -3
  166. package/src/domains/eval/metrics/evidence.ts +0 -116
  167. package/src/domains/eval/metrics/invariants.ts +1 -1
  168. package/src/domains/eval/runners/clio-run.ts +1 -10
  169. package/src/domains/eval/runners/external-command.ts +2 -29
  170. package/src/domains/eval/schema/suite.ts +0 -7
  171. package/src/domains/eval/suites/run.ts +1 -7
  172. package/src/domains/memory/index.ts +22 -0
  173. package/src/domains/memory/operations.ts +58 -1
  174. package/src/domains/memory/promotion.ts +281 -0
  175. package/src/domains/memory/prompt-section.ts +25 -5
  176. package/src/domains/memory/proposal.ts +51 -7
  177. package/src/domains/memory/task-bank.ts +3 -2
  178. package/src/domains/memory/task-memory-handoff.ts +181 -24
  179. package/src/domains/memory/task-memory-policy.ts +3 -1
  180. package/src/domains/memory/types.ts +37 -0
  181. package/src/domains/memory/validate.ts +178 -0
  182. package/src/domains/middleware/memory-intervention.ts +35 -25
  183. package/src/domains/middleware/runtime.ts +6 -0
  184. package/src/domains/middleware/skills-reminder.ts +19 -4
  185. package/src/domains/middleware/stalled-turn.ts +43 -1
  186. package/src/domains/middleware/types.ts +10 -0
  187. package/src/domains/observability/contract.ts +6 -1
  188. package/src/domains/observability/cost.ts +20 -4
  189. package/src/domains/observability/extension.ts +2 -2
  190. package/src/domains/providers/index.ts +3 -0
  191. package/src/domains/providers/model-discovery.ts +9 -0
  192. package/src/domains/providers/runtime-resolution.ts +38 -1
  193. package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
  194. package/src/domains/providers/types/context-window-slots.ts +18 -0
  195. package/src/domains/providers/types/runtime-descriptor.ts +3 -1
  196. package/src/domains/safety/call-target.ts +211 -14
  197. package/src/domains/safety/decision-presentation.ts +268 -0
  198. package/src/domains/safety/redaction.ts +73 -0
  199. package/src/domains/session/context-ledger.ts +10 -1
  200. package/src/domains/session/decision-board.ts +4 -0
  201. package/src/domains/session/entries.ts +3 -0
  202. package/src/domains/session/history.ts +68 -19
  203. package/src/domains/session/usage.ts +24 -7
  204. package/src/engine/acp/event-mapper.ts +7 -0
  205. package/src/engine/acp/server.ts +29 -2
  206. package/src/engine/apis/lmstudio.ts +25 -4
  207. package/src/engine/apis/openai-completions.ts +147 -22
  208. package/src/engine/claude/sdk-runtime.ts +8 -2
  209. package/src/engine/claude/tool-safety.ts +13 -0
  210. package/src/engine/loop-guard.ts +27 -3
  211. package/src/engine/worker-events.ts +4 -3
  212. package/src/engine/worker-runtime.ts +59 -54
  213. package/src/entry/orchestrator.ts +18 -1
  214. package/src/interactive/chat-loop-messages.ts +22 -0
  215. package/src/interactive/chat-loop.ts +13 -0
  216. package/src/interactive/chat-renderer.ts +19 -3
  217. package/src/interactive/clio-editor.ts +44 -7
  218. package/src/interactive/context-overlay.ts +43 -5
  219. package/src/interactive/cost-overlay.ts +39 -8
  220. package/src/interactive/dispatch-board.ts +212 -35
  221. package/src/interactive/footer/widgets.ts +13 -0
  222. package/src/interactive/interactive-application.ts +6 -1
  223. package/src/interactive/interactive-input-runtime.ts +11 -1
  224. package/src/interactive/interactive-presentation.ts +11 -1
  225. package/src/interactive/memory-overlay.ts +89 -4
  226. package/src/interactive/overlay-ask-user-lifecycle.ts +1 -1
  227. package/src/interactive/overlay-frame.ts +5 -2
  228. package/src/interactive/overlay-general-openers.ts +40 -1
  229. package/src/interactive/overlay-key-routing.ts +41 -1
  230. package/src/interactive/overlay-lifecycle.ts +11 -4
  231. package/src/interactive/overlay-permission-lifecycle.ts +23 -8
  232. package/src/interactive/overlay-transitions.ts +11 -0
  233. package/src/interactive/overlays/ask-user.ts +74 -30
  234. package/src/interactive/overlays/decisions.ts +3 -1
  235. package/src/interactive/permission-hint.ts +35 -0
  236. package/src/interactive/permission-overlay.ts +95 -45
  237. package/src/interactive/renderers/tool-execution.ts +19 -49
  238. package/src/interactive/session-last-turn.ts +8 -1
  239. package/src/interactive/session-usage-reseed.ts +36 -10
  240. package/src/interactive/slash-commands.ts +2 -2
  241. package/src/interactive/status/summary.ts +5 -0
  242. package/src/interactive/status/types.ts +5 -0
  243. package/src/interactive/terminal-lease.ts +1 -0
  244. package/src/interactive/turn-context.ts +96 -23
  245. package/src/interactive/turn-middleware.ts +1 -0
  246. package/src/interactive/turn-runtime.ts +37 -8
  247. package/src/interactive/turn-state.ts +3 -0
  248. package/src/interactive/worker-progress.ts +440 -0
  249. package/src/interactive/worker-stream.ts +51 -110
  250. package/src/tools/agent-tools.ts +28 -3
  251. package/src/tools/ask-user.ts +21 -1
  252. package/src/tools/context/index.ts +2 -2
  253. package/src/tools/dispatch-arguments.ts +8 -0
  254. package/src/tools/dispatch-event-text.ts +19 -0
  255. package/src/tools/dispatch.ts +24 -1
  256. package/src/tools/monitor.ts +15 -0
  257. package/src/tools/registry.ts +15 -5
  258. package/src/tools/result-disposition.ts +156 -0
  259. package/src/tools/result-shaping.ts +59 -1
  260. package/src/tools/verify/authoring.ts +55 -54
  261. package/src/tools/worker-evidence.ts +19 -0
  262. package/src/worker/spec-contract.ts +43 -3
  263. package/dist/chunk-EFADSJET.js +0 -18
  264. package/dist/memory-4ALKDJ4Q.js +0 -246
  265. package/src/domains/eval/metrics/chaos-stream.ts +0 -93
@@ -549,8 +549,277 @@ function clioTheme() {
549
549
 
550
550
  // src/interactive/clio-editor.ts
551
551
  init_esm_shims();
552
+
553
+ // src/interactive/overlay-frame.ts
554
+ init_esm_shims();
555
+ var DEFAULT_SELECT_THEME = selectListTheme(clioTheme());
556
+ var DEFAULT_SETTINGS_THEME = settingsListTheme(clioTheme());
557
+ var FocusBox = class extends Box {
558
+ inputTarget;
559
+ onInput;
560
+ constructor(children, options) {
561
+ super(options?.x ?? 1, options?.y ?? 0);
562
+ const childList = Array.isArray(children) ? children : [children];
563
+ for (const child of childList) this.addChild(child);
564
+ this.inputTarget = options?.inputTarget === void 0 ? childList[0] ?? null : options.inputTarget;
565
+ this.onInput = options?.onInput;
566
+ }
567
+ handleInput(data) {
568
+ if (this.onInput) {
569
+ this.onInput(data);
570
+ return;
571
+ }
572
+ this.inputTarget?.handleInput?.(data);
573
+ }
574
+ };
575
+ function resolveTone(tone) {
576
+ return typeof tone === "function" ? tone() : tone;
577
+ }
578
+ function clioFrame(text, token = "frame") {
579
+ return clioTheme().fg(token, text);
580
+ }
581
+ function clioTitle(text, token) {
582
+ return token === void 0 ? screenTitle(clioTheme(), text) : clioTheme().style(token, text, { bold: true });
583
+ }
584
+ function clioError(text) {
585
+ return clioTheme().fg("error", text);
586
+ }
587
+ function brandedTopBorder(label, innerWidth, tone) {
588
+ const frame2 = (text) => clioFrame(text, tone ?? "frame");
589
+ const clean = label.replace(/^[┌┐└┘├┤─│\s]+/, "").replace(/[┌┐└┘├┤─│\s]+$/, "");
590
+ const formatted = clean.length > 0 ? `\u2500 ${clean} ` : "\u2500";
591
+ const clipped = visibleWidth(formatted) > innerWidth ? truncateToWidth(formatted, innerWidth, "\u2026", true) : formatted;
592
+ const fill = "\u2500".repeat(Math.max(0, innerWidth - visibleWidth(clipped)));
593
+ const cleanIndex = clipped.indexOf(clean);
594
+ if (cleanIndex !== -1) {
595
+ const prefix = clipped.slice(0, cleanIndex);
596
+ const suffix = clipped.slice(cleanIndex + clean.length);
597
+ return `${frame2("\u250C")}${frame2(prefix)}${clioTitle(clean, tone)}${frame2(suffix)}${frame2(fill)}${frame2("\u2510")}`;
598
+ }
599
+ return `${frame2("\u250C")}${frame2(clipped)}${frame2(fill)}${frame2("\u2510")}`;
600
+ }
601
+ function isCriticalHintKey(key) {
602
+ const canonical = canonicalizeKey(key);
603
+ return canonical === "Esc" || canonical === "Enter" || canonical === "Enter/Space" || canonical === "type";
604
+ }
605
+ function isCriticalEntry(entry) {
606
+ return entry.critical ?? isCriticalHintKey(entry.key);
607
+ }
608
+ function renderHintEntries(entries, short) {
609
+ return entries.map((entry) => `[${canonicalizeKey(entry.key)}] ${short ? entry.short ?? entry.verb : entry.verb}`).join(" \xB7 ");
610
+ }
611
+ function fitHintEntries(entries, maxWidth) {
612
+ if (entries.length === 0) return "";
613
+ for (const short of [false, true]) {
614
+ const rendered = renderHintEntries(entries, short);
615
+ if (visibleWidth(rendered) <= maxWidth) return rendered;
616
+ }
617
+ const kept = [...entries];
618
+ for (const criticalPass of [false, true]) {
619
+ while (kept.length > 1) {
620
+ const index = kept.findIndex((entry) => criticalPass || !isCriticalEntry(entry));
621
+ if (index === -1) break;
622
+ kept.splice(index, 1);
623
+ const rendered = renderHintEntries(kept, true);
624
+ if (visibleWidth(rendered) <= maxWidth) return rendered;
625
+ }
626
+ }
627
+ return renderHintEntries(kept, true);
628
+ }
629
+ var FILTER_HINT = { key: "type", verb: "filter" };
630
+ function canonicalizeKey(key) {
631
+ const trimmed = key.trim();
632
+ if (trimmed === "R") return "R";
633
+ const lower = trimmed.toLowerCase();
634
+ if (lower === "up/down" || lower === "updown" || lower === "\u2191/\u2193" || lower === "up/down/j/k" || lower === "\u2191\u2193")
635
+ return "\u2191\u2193";
636
+ if (lower === "enter/space") return "Enter/Space";
637
+ if (lower === "enter") return "Enter";
638
+ if (lower === "esc" || lower === "escape") return "Esc";
639
+ if (lower === "space") return "Space";
640
+ if (lower === "tab") return "Tab";
641
+ if (lower === "r") return "r";
642
+ if (lower === "type") return "type";
643
+ return trimmed;
644
+ }
645
+ function buildHint(entries, esc = "close") {
646
+ const finalEntries = [
647
+ ...entries.map((e) => ({ key: canonicalizeKey(e.key), verb: e.verb })),
648
+ { key: "Esc", verb: esc }
649
+ ];
650
+ return finalEntries.map((e) => `[${e.key}] ${e.verb}`).join(" \xB7 ");
651
+ }
652
+ function elideHint(hint, maxCleanWidth) {
653
+ const parts = hint.split(" \xB7 ");
654
+ if (parts.length <= 2) return hint;
655
+ const entries = parts.map((part) => {
656
+ const match = /^\[([^\]]+)\] ([\s\S]+)$/u.exec(part);
657
+ if (!match) return { key: "", verb: part, critical: false };
658
+ return { key: match[1] ?? "", verb: match[2] ?? "" };
659
+ });
660
+ const rendered = fitHintEntries(entries, maxCleanWidth);
661
+ return rendered.replace(/\[\] /gu, "");
662
+ }
663
+ function brandedBottomBorder(innerWidth, hint, tone) {
664
+ const frame2 = (text) => clioFrame(text, tone ?? "frame");
665
+ if (!hint || hint.trim().length === 0) {
666
+ return `${frame2("\u2514")}${frame2("\u2500".repeat(innerWidth))}${frame2("\u2518")}`;
667
+ }
668
+ let clean = hint.trim();
669
+ const maxCleanWidth = innerWidth - 3;
670
+ if (clean.includes(" \xB7 ") && visibleWidth(`\u2500 ${clean} `) > innerWidth) {
671
+ clean = elideHint(clean, maxCleanWidth);
672
+ }
673
+ const formatted = `\u2500 ${clean} `;
674
+ const clipped = visibleWidth(formatted) > innerWidth ? truncateToWidth(formatted, innerWidth, "\u2026", true) : formatted;
675
+ const fill = "\u2500".repeat(Math.max(0, innerWidth - visibleWidth(clipped)));
676
+ const cleanIndex = clipped.indexOf(clean);
677
+ if (cleanIndex !== -1) {
678
+ const prefix = clipped.slice(0, cleanIndex);
679
+ const suffix = clipped.slice(cleanIndex + clean.length);
680
+ return `${frame2("\u2514")}${frame2(prefix)}${clioTheme().fg("dim", clean)}${frame2(suffix)}${frame2(fill)}${frame2("\u2518")}`;
681
+ }
682
+ return `${frame2("\u2514")}${frame2(clipped)}${frame2(fill)}${frame2("\u2518")}`;
683
+ }
684
+ function formatRuntimeResolutionDiagnostic(diagnostic) {
685
+ return `${diagnostic.severity}: ${diagnostic.code}: ${diagnostic.message}`;
686
+ }
687
+ function diagnosticSeverityToken(severity) {
688
+ return severity === "error" ? "error" : severity === "warning" ? "warning" : "muted";
689
+ }
690
+ function runtimeResolutionDiagnosticLine(diagnostic, width) {
691
+ return clioTheme().fg(diagnosticSeverityToken(diagnostic.severity), fitDiagnosticLine(diagnostic, width));
692
+ }
693
+ function fitDiagnosticLine(diagnostic, width) {
694
+ return padAnsi(formatRuntimeResolutionDiagnostic(diagnostic), Math.max(1, width));
695
+ }
696
+ function frameAlignForAnchor(anchor) {
697
+ if (anchor === void 0) return "center";
698
+ if (anchor === "left-center" || anchor.endsWith("-left")) return "left";
699
+ if (anchor === "right-center" || anchor.endsWith("-right")) return "right";
700
+ return "center";
701
+ }
702
+ function fitBody(lines, rowBudget, contentWidth) {
703
+ if (rowBudget <= 0) return lines;
704
+ const bodyBudget = Math.max(1, rowBudget - 2);
705
+ if (lines.length <= bodyBudget) return lines;
706
+ const kept = lines.slice(0, bodyBudget - 1);
707
+ const hidden = lines.length - kept.length;
708
+ return [...kept, clioTheme().fg("dim", truncateToWidth(`\u2026 ${hidden} more rows`, contentWidth, "", true))];
709
+ }
710
+ var ClioOverlayFrame = class {
711
+ constructor(child, title, footerHint, boxWidth = 0, align = "center", tone) {
712
+ this.child = child;
713
+ this.title = title;
714
+ this.footerHint = footerHint;
715
+ this.boxWidth = boxWidth;
716
+ this.align = align;
717
+ this.tone = tone;
718
+ }
719
+ child;
720
+ title;
721
+ footerHint;
722
+ boxWidth;
723
+ align;
724
+ tone;
725
+ /**
726
+ * Rows the box may occupy, or zero while unknown.
727
+ *
728
+ * `Component.render` is handed a width and nothing else, so the frame learns
729
+ * its height budget from the engine's `visible` predicate, which is called
730
+ * with the live terminal size immediately before the render pass that
731
+ * composites this overlay.
732
+ */
733
+ rowBudget = 0;
734
+ /**
735
+ * Last rendered box, keyed by everything that shapes it. `childLines` is
736
+ * compared by array identity: a child that rebuilds its rows returns a fresh
737
+ * array and correctly misses, and one that serves a cache returns the same
738
+ * array and correctly hits.
739
+ */
740
+ cachedRender;
741
+ setRowBudget(rows) {
742
+ this.rowBudget = Math.max(0, Math.floor(rows));
743
+ }
744
+ render(width) {
745
+ const boxWidth = Math.max(5, Math.min(this.boxWidth > 0 ? this.boxWidth : width, width));
746
+ const contentWidth = Math.max(1, boxWidth - 4);
747
+ const childLines = this.child.render(contentWidth);
748
+ const titleText = typeof this.title === "function" ? this.title() : this.title;
749
+ const hint = typeof this.footerHint === "function" ? this.footerHint(contentWidth + 2) : this.footerHint;
750
+ const tone = resolveTone(this.tone);
751
+ const cached = this.cachedRender;
752
+ if (cached !== void 0 && cached.width === width && cached.rowBudget === this.rowBudget && cached.childLines === childLines && cached.title === titleText && cached.hint === hint && cached.tone === tone) {
753
+ return cached.lines;
754
+ }
755
+ const label = titleText.length > 0 ? `\u2500 ${titleText} ` : "\u2500 ";
756
+ const side = clioFrame("\u2502", tone ?? "frame");
757
+ const boxLines = [
758
+ brandedTopBorder(label, contentWidth + 2, tone),
759
+ ...fitBody(childLines, this.rowBudget, contentWidth).map((line) => `${side} ${padAnsi(line, contentWidth)} ${side}`),
760
+ brandedBottomBorder(contentWidth + 2, hint, tone)
761
+ ];
762
+ const slack = Math.max(0, width - boxWidth);
763
+ const lines = (() => {
764
+ if (slack === 0) return boxLines;
765
+ const leading = this.align === "left" ? 0 : this.align === "right" ? slack : Math.floor(slack / 2);
766
+ const lead = " ".repeat(leading);
767
+ const trail = " ".repeat(slack - leading);
768
+ return boxLines.map((line) => `${lead}${line}${trail}`);
769
+ })();
770
+ this.cachedRender = { width, rowBudget: this.rowBudget, childLines, title: titleText, hint, tone, lines };
771
+ return lines;
772
+ }
773
+ handleInput(data) {
774
+ this.child.handleInput?.(data);
775
+ }
776
+ invalidate() {
777
+ this.cachedRender = void 0;
778
+ this.child.invalidate?.();
779
+ }
780
+ };
781
+ function showClioOverlayFrame(tui, child, options) {
782
+ const { title, footerHint, tone, width, visible, maxHeight, margin, ...overlayOptions } = options;
783
+ const boxWidth = typeof width === "number" ? width : 0;
784
+ const frame2 = new ClioOverlayFrame(child, title, footerHint, boxWidth, frameAlignForAnchor(options.anchor), tone);
785
+ return tui.showOverlay(frame2, {
786
+ ...overlayOptions,
787
+ ...margin !== void 0 ? { margin } : {},
788
+ width: "100%",
789
+ visible: (termWidth, termHeight) => {
790
+ const shown = visible ? visible(termWidth, termHeight) : true;
791
+ const marginRows = typeof margin === "number" ? margin * 2 : (margin?.top ?? 0) + (margin?.bottom ?? 0);
792
+ const available = Math.max(1, termHeight - marginRows);
793
+ const requested = resolveRowSize(maxHeight, termHeight);
794
+ frame2.setRowBudget(requested === null ? available : Math.min(requested, available));
795
+ return shown;
796
+ }
797
+ });
798
+ }
799
+ function resolveRowSize(value, termHeight) {
800
+ if (typeof value === "number") return Math.max(1, Math.floor(value));
801
+ if (typeof value !== "string") return null;
802
+ const percent = /^(\d+(?:\.\d+)?)%$/u.exec(value.trim());
803
+ if (!percent?.[1]) return null;
804
+ return Math.max(1, Math.floor(termHeight * Number.parseFloat(percent[1]) / 100));
805
+ }
806
+
807
+ // src/interactive/permission-hint.ts
808
+ init_esm_shims();
809
+ function permissionHintEntries(composerHasDraft = false) {
810
+ return [
811
+ composerHasDraft ? { key: "Backspace", verb: "clear the draft to allow", short: "clear draft", critical: true } : { key: "Enter", verb: "allow once", short: "allow", critical: true },
812
+ { key: "s", verb: "stop turn", short: "stop", critical: true },
813
+ // With a draft, deny and stop are the only immediate answers, so Esc
814
+ // outranks the narrowing that would otherwise drop it first.
815
+ { key: "Esc", verb: "deny", critical: composerHasDraft }
816
+ ];
817
+ }
818
+
819
+ // src/interactive/clio-editor.ts
552
820
  var REVERSE_VIDEO_BLANK = `${String.fromCharCode(27)}[7m ${String.fromCharCode(27)}[0m`;
553
821
  var EMPTY_PROMPT = "Ask Clio\u2026 / for commands";
822
+ var CONFIRM_PROMPT = "A parked call is waiting for your decision";
554
823
  var MIN_HINT_WIDTH = 60;
555
824
  function hasScrollIndicator(line) {
556
825
  const stripped = stripTerminalSequences(line);
@@ -579,6 +848,7 @@ function styledRailLabel(theme, chrome) {
579
848
  return `${theme.fg("dim", chrome.getModelLabel())} ${theme.fg("dim", "\xB7")} ${styledThinkingHint(theme, chrome.getThinkingLabel())}`;
580
849
  }
581
850
  function composerMode(chrome, text) {
851
+ if (chrome.isAwaitingApproval?.() ?? false) return "CONFIRM";
582
852
  if (!(chrome.isStreaming?.() ?? false)) return "MESSAGE";
583
853
  const willSteer = chrome.willEnterSteer?.(text) ?? text.trim().length > 0;
584
854
  return willSteer ? "STEER" : "FOLLOW-UP";
@@ -589,12 +859,20 @@ function lowerRailHint(theme, chrome) {
589
859
  `${chrome.getSubmitKeyLabel?.() ?? "Enter"} send \xB7 ${chrome.getNewlineKeyLabel?.() ?? "Shift+Enter"} newline`
590
860
  );
591
861
  }
592
- function renderEmptyPrompt(line, width, theme) {
862
+ function confirmRailHint(theme, width, hasDraft) {
863
+ return theme.fg("warning", fitHintEntries(permissionHintEntries(hasDraft), Math.max(1, width - 3)));
864
+ }
865
+ function modeToken(mode) {
866
+ if (mode === "STEER") return "action";
867
+ if (mode === "CONFIRM") return "warning";
868
+ return "accentDeep";
869
+ }
870
+ function renderEmptyPrompt(line, width, theme, text = EMPTY_PROMPT) {
593
871
  const cursorAt = line.indexOf(REVERSE_VIDEO_BLANK);
594
872
  if (cursorAt < 0) return line;
595
873
  const afterCursorAt = cursorAt + REVERSE_VIDEO_BLANK.length;
596
874
  const available = Math.max(0, width - 1);
597
- const prompt = truncateToWidth(theme.fg("dim", EMPTY_PROMPT), available, "\u2026", false);
875
+ const prompt = truncateToWidth(theme.fg("dim", text), available, "\u2026", false);
598
876
  const consumed = visibleWidth(prompt);
599
877
  return `${line.slice(0, afterCursorAt)}${prompt}${line.slice(afterCursorAt + consumed)}`;
600
878
  }
@@ -619,21 +897,30 @@ var ClioEditor = class extends Editor {
619
897
  const text = this.getText();
620
898
  const mode = composerMode(this.chrome, text);
621
899
  if (hasScrollIndicator(lines[0] ?? "")) {
622
- const modeLabel = theme.style(mode === "STEER" ? "action" : "accentDeep", mode, { bold: true });
900
+ const modeLabel = theme.style(modeToken(mode), mode, { bold: true });
623
901
  lines[0] = truncateToWidth(`${modeLabel} ${lines[0] ?? ""}`, safeWidth, "", true);
624
902
  } else {
625
903
  lines[0] = rule(theme, safeWidth, {
626
904
  left: mode,
627
- leftToken: mode === "STEER" ? "action" : "accentDeep",
905
+ leftToken: modeToken(mode),
628
906
  right: styledRailLabel(theme, this.chrome),
629
907
  fillToken: "frameStrong",
630
908
  rightRaw: true,
631
909
  rightTail: theme.style("frameStrong", "\u2500", { bold: true })
632
910
  });
633
911
  }
634
- if (text.length === 0 && lines[1]) lines[1] = renderEmptyPrompt(lines[1], safeWidth, theme);
912
+ if (text.length === 0 && lines[1]) {
913
+ lines[1] = renderEmptyPrompt(lines[1], safeWidth, theme, mode === "CONFIRM" ? CONFIRM_PROMPT : EMPTY_PROMPT);
914
+ }
635
915
  const bottomRail = findBottomRail(lines, safeWidth);
636
- if (bottomRail >= 0 && safeWidth >= MIN_HINT_WIDTH) {
916
+ if (bottomRail >= 0 && mode === "CONFIRM") {
917
+ lines[bottomRail] = rule(theme, safeWidth, {
918
+ right: confirmRailHint(theme, safeWidth, text.length > 0),
919
+ fillToken: "frameStrong",
920
+ rightRaw: true,
921
+ rightTail: theme.style("frameStrong", "\u2500", { bold: true })
922
+ });
923
+ } else if (bottomRail >= 0 && safeWidth >= MIN_HINT_WIDTH) {
637
924
  lines[bottomRail] = rule(theme, safeWidth, {
638
925
  right: lowerRailHint(theme, this.chrome),
639
926
  fillToken: "frameStrong",
@@ -1825,7 +2112,6 @@ function createKeybindingManager(settings, env = process.env) {
1825
2112
  export {
1826
2113
  SelectList,
1827
2114
  createAgentProgress,
1828
- Box,
1829
2115
  CombinedAutocompleteProvider,
1830
2116
  Container,
1831
2117
  fuzzyFilter,
@@ -1857,7 +2143,6 @@ export {
1857
2143
  joinSections,
1858
2144
  markdownTheme,
1859
2145
  selectListTheme,
1860
- settingsListTheme,
1861
2146
  abbreviateModelId,
1862
2147
  formatTargetLabel,
1863
2148
  formatCompactMs,
@@ -1869,6 +2154,16 @@ export {
1869
2154
  frame,
1870
2155
  innerDivider,
1871
2156
  clioTheme,
2157
+ DEFAULT_SELECT_THEME,
2158
+ FocusBox,
2159
+ clioError,
2160
+ fitHintEntries,
2161
+ FILTER_HINT,
2162
+ buildHint,
2163
+ formatRuntimeResolutionDiagnostic,
2164
+ runtimeResolutionDiagnosticLine,
2165
+ showClioOverlayFrame,
2166
+ permissionHintEntries,
1872
2167
  ClioEditor,
1873
2168
  getActiveRenderTrace,
1874
2169
  createProcessInteractiveShell,
@@ -1879,4 +2174,4 @@ export {
1879
2174
  formatPlatformKeybindingNotice,
1880
2175
  createKeybindingManager
1881
2176
  };
1882
- //# sourceMappingURL=chunk-ZWMF7253.js.map
2177
+ //# sourceMappingURL=chunk-E2ER4LJF.js.map
@@ -660,7 +660,7 @@ function resultContractRepairMessage(input) {
660
660
  const lines = [
661
661
  last ? "FINAL RESULT REQUIRED IN THIS RESPONSE. Your previous response still did not satisfy this run's result contract." : "Your previous response did not satisfy this run's result contract.",
662
662
  `Validator reason: ${input.reason}`,
663
- "Tool use is over. Answer from the evidence you already gathered.",
663
+ input.toolsAvailable === true ? "You may use the admitted tools to repair this validator failure, then emit the required terminal result." : "Tool use is over. Answer from the evidence you already gathered.",
664
664
  `Emit exactly this shape and nothing else: ${resultContractShape(input.contract)}`,
665
665
  "Do not add prose, code fences, or commentary around it. Do not describe work you intend to do next."
666
666
  ];
@@ -1104,72 +1104,6 @@ function asRecord(value) {
1104
1104
  return value !== null && typeof value === "object" ? value : null;
1105
1105
  }
1106
1106
 
1107
- // src/domains/safety/autonomy.ts
1108
- init_esm_shims();
1109
- var AUTONOMY_LEVELS = ["read-only", "suggest", "auto-edit", "full-auto"];
1110
- var DEFAULT_AUTONOMY_LEVEL = "auto-edit";
1111
- function isAutonomyLevel(value) {
1112
- return typeof value === "string" && AUTONOMY_LEVELS.includes(value);
1113
- }
1114
- var DEFAULT_AUTONOMY_EXPOSURE = "local";
1115
- function mapAutonomy(level, actionClass, options = {}) {
1116
- if (actionClass === "git_destructive") return "deny";
1117
- if ((level === "auto-edit" || level === "suggest") && options.exposure === "outward") return "ask";
1118
- if (actionClass === "read") return "allow";
1119
- if (level === "read-only") return "deny";
1120
- if (level === "suggest") return "ask";
1121
- switch (actionClass) {
1122
- case "write":
1123
- return "allow";
1124
- case "dispatch":
1125
- if (options.dispatchPlanScale === true && level !== "full-auto") return "ask";
1126
- return "allow";
1127
- case "execute": {
1128
- if (options.executeRecognized !== false) return "allow";
1129
- return level === "full-auto" ? "allow" : "ask";
1130
- }
1131
- case "unknown":
1132
- return "ask";
1133
- default:
1134
- return "ask";
1135
- }
1136
- }
1137
- function autonomyDenyRejection(level, tool, actionClass) {
1138
- return {
1139
- short: `${tool} denied: autonomy level is ${level}`,
1140
- detail: `Clio is at autonomy ${level}: ${actionClass} actions are denied without prompting. Describe the change you would make instead, so the operator can apply it or raise the autonomy level.`,
1141
- hints: ["Propose the exact edit or command as text.", "The operator can change the level in /settings."]
1142
- };
1143
- }
1144
- function autonomyAskRejection(level, tool, actionClass, exposure = DEFAULT_AUTONOMY_EXPOSURE) {
1145
- if (exposure === "outward") {
1146
- return {
1147
- short: `${tool} needs approval: outward-facing gate at autonomy ${level}`,
1148
- detail: `The call declared exposure=outward, so answering it publishes or sends something outside the workspace. Autonomy ${level} auto-answers local gates and parks outward-facing ones for the operator.`,
1149
- hints: [
1150
- "Approving resumes only this call.",
1151
- "Autonomy full-auto answers outward gates too; the safety net still applies there."
1152
- ]
1153
- };
1154
- }
1155
- return {
1156
- short: `${tool} needs approval (${actionClass}) at autonomy ${level}`,
1157
- detail: `Autonomy ${level} routes ${actionClass} actions through operator approval. The call is parked until the operator approves it once or cancels it.`,
1158
- hints: [
1159
- "Approving resumes only this call.",
1160
- "Recognized commands can be added to .clio-coder/safety.yaml.",
1161
- // The sanctioned pivots for a gated shell command: typed verification
1162
- // and read-class observe tools run without approval at this level,
1163
- // and models otherwise stall retrying denied bash for checks or
1164
- // directory listings.
1165
- ...actionClass === "execute" ? [
1166
- 'A declared package or project-catalog check runs without approval through the verify tool: verify(check="<id>").',
1167
- "Read-only inspection runs without approval through the ls, read, grep, and find tools."
1168
- ] : []
1169
- ]
1170
- };
1171
- }
1172
-
1173
1107
  // src/domains/safety/path-policy.ts
1174
1108
  init_esm_shims();
1175
1109
  import { homedir } from "node:os";
@@ -2479,13 +2413,6 @@ export {
2479
2413
  RESULT_CONTRACT_REPAIR_LIMIT,
2480
2414
  resultContractRepairMessages,
2481
2415
  parseResultContract,
2482
- AUTONOMY_LEVELS,
2483
- DEFAULT_AUTONOMY_LEVEL,
2484
- isAutonomyLevel,
2485
- DEFAULT_AUTONOMY_EXPOSURE,
2486
- mapAutonomy,
2487
- autonomyDenyRejection,
2488
- autonomyAskRejection,
2489
2416
  DEFAULT_RECENT_ENTRY_LIMIT,
2490
2417
  assessFinishContract,
2491
2418
  typedValidationSummary,
@@ -2493,4 +2420,4 @@ export {
2493
2420
  WRITE_ROOT_REFUSED_TOOLS,
2494
2421
  createSafetyPolicyEngine
2495
2422
  };
2496
- //# sourceMappingURL=chunk-7RXG6QRZ.js.map
2423
+ //# sourceMappingURL=chunk-EKY57CSP.js.map
@@ -4,9 +4,10 @@ import {
4
4
  TOOL_PROFILE_NAMES,
5
5
  classifyAgentTask,
6
6
  cloneApprovedAssignmentRoute,
7
+ cloneDispatchBudgetRequest,
7
8
  isApprovedAssignmentRoute,
8
9
  isToolProfileName
9
- } from "./chunk-ZYKPLLNQ.js";
10
+ } from "./chunk-XXQNGV4M.js";
10
11
  import {
11
12
  ROUTE_POLICY_VERSION,
12
13
  isExecutionRole,
@@ -147,6 +148,13 @@ function dispatchRequestFromArgs(args, options) {
147
148
  }
148
149
  request.thinkingLevel = thinkingLevel;
149
150
  }
151
+ if (args.budget !== void 0) {
152
+ try {
153
+ request.budget = cloneDispatchBudgetRequest(args.budget);
154
+ } catch (error) {
155
+ return { ok: false, message: error instanceof Error ? error.message : String(error) };
156
+ }
157
+ }
150
158
  return { ok: true, request };
151
159
  }
152
160
  function dispatchRequestsFromArgs(args, options) {
@@ -641,4 +649,4 @@ export {
641
649
  withResolvedDispatchPlan,
642
650
  describeDispatchPlan
643
651
  };
644
- //# sourceMappingURL=chunk-EDRHSCIE.js.map
652
+ //# sourceMappingURL=chunk-EYPA3EGJ.js.map
@@ -67,4 +67,4 @@ export {
67
67
  BusChannels,
68
68
  isRunAbortedPayload
69
69
  };
70
- //# sourceMappingURL=chunk-TTNYS3EA.js.map
70
+ //# sourceMappingURL=chunk-G7MUEIGA.js.map
@@ -191,6 +191,7 @@ function buildContextLedger(input) {
191
191
  model: input.model ?? null,
192
192
  contextWindow: window,
193
193
  contextWindowSource: input.contextWindowSource ?? null,
194
+ contextWindowSlots: input.contextWindowSlots ?? null,
194
195
  usedTokens,
195
196
  reserveTokens,
196
197
  freeTokens,
@@ -609,4 +610,4 @@ export {
609
610
  snapshotInputTokens,
610
611
  reconcileSnapshot
611
612
  };
612
- //# sourceMappingURL=chunk-BPGS2WCQ.js.map
613
+ //# sourceMappingURL=chunk-GEYXPTRF.js.map
@@ -1,4 +1,7 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
+ import {
3
+ AUTONOMY_EXPOSURES
4
+ } from "./chunk-HWUFFB6L.js";
2
5
  import {
3
6
  init_esm_shims
4
7
  } from "./chunk-3R73A4XB.js";
@@ -234,7 +237,7 @@ function isSessionEntry(value) {
234
237
  case "taskLedger":
235
238
  return isOptionalString(v.boardId) && Array.isArray(v.goals) && v.goals.every(isTaskLedgerGoal) && Array.isArray(v.subgoals) && v.subgoals.every(isTaskLedgerGoal) && isStringArray(v.activeRunIds) && Array.isArray(v.requiredValidationEvidence) && v.requiredValidationEvidence.every(isTaskLedgerEvidence);
236
239
  case "decisionLedger":
237
- return isString(v.interviewId) && isOneOf(v.interviewStatus, DECISION_INTERVIEW_STATUSES) && isString(v.startedAt) && isString(v.endedAt) && isNumber(v.roundCount) && Number.isInteger(v.roundCount) && v.roundCount >= 0 && isOptionalString(v.summary) && isOptionalString(v.transcriptPath) && Array.isArray(v.decisions) && v.decisions.every(isDecisionRecord);
240
+ return isString(v.interviewId) && isOneOf(v.interviewStatus, DECISION_INTERVIEW_STATUSES) && isString(v.startedAt) && isString(v.endedAt) && isNumber(v.roundCount) && Number.isInteger(v.roundCount) && v.roundCount >= 0 && isOptionalString(v.summary) && isOptionalString(v.transcriptPath) && (v.exposure === void 0 || isOneOf(v.exposure, AUTONOMY_EXPOSURES)) && Array.isArray(v.decisions) && v.decisions.every(isDecisionRecord);
238
241
  case "workerRun":
239
242
  return isString(v.assignmentId) && isString(v.runId) && isOneOf(v.origin, WORKER_RUN_ORIGINS) && isString(v.agentId) && isWorkerRunRuntime(v.runtime) && isOptionalString(v.parentToolCallId);
240
243
  case "contextEviction":
@@ -255,4 +258,4 @@ export {
255
258
  isSessionHeader,
256
259
  isSessionEntry
257
260
  };
258
- //# sourceMappingURL=chunk-BEY543CS.js.map
261
+ //# sourceMappingURL=chunk-GOXNB3AO.js.map
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
2
  import {
3
3
  detectProjectType
4
- } from "./chunk-YHZX5GEU.js";
4
+ } from "./chunk-XAKHZX5N.js";
5
5
  import {
6
6
  init_esm_shims
7
7
  } from "./chunk-3R73A4XB.js";
@@ -179,4 +179,4 @@ export {
179
179
  probeWorkspace,
180
180
  probeWorkspaceAsync
181
181
  };
182
- //# sourceMappingURL=chunk-G4BMMOKF.js.map
182
+ //# sourceMappingURL=chunk-HVDIIIQW.js.map
@@ -0,0 +1,83 @@
1
+ import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-3R73A4XB.js";
5
+
6
+ // src/domains/safety/autonomy.ts
7
+ init_esm_shims();
8
+ var AUTONOMY_LEVELS = ["read-only", "suggest", "auto-edit", "full-auto"];
9
+ var DEFAULT_AUTONOMY_LEVEL = "auto-edit";
10
+ function isAutonomyLevel(value) {
11
+ return typeof value === "string" && AUTONOMY_LEVELS.includes(value);
12
+ }
13
+ var AUTONOMY_EXPOSURES = ["local", "outward"];
14
+ var DEFAULT_AUTONOMY_EXPOSURE = "local";
15
+ function mapAutonomy(level, actionClass, options = {}) {
16
+ if (actionClass === "git_destructive") return "deny";
17
+ if ((level === "auto-edit" || level === "suggest") && options.exposure === "outward") return "ask";
18
+ if (actionClass === "read") return "allow";
19
+ if (level === "read-only") return "deny";
20
+ if (level === "suggest") return "ask";
21
+ switch (actionClass) {
22
+ case "write":
23
+ return "allow";
24
+ case "dispatch":
25
+ if (options.dispatchPlanScale === true && level !== "full-auto") return "ask";
26
+ return "allow";
27
+ case "execute": {
28
+ if (options.executeRecognized !== false) return "allow";
29
+ return level === "full-auto" ? "allow" : "ask";
30
+ }
31
+ case "unknown":
32
+ return "ask";
33
+ default:
34
+ return "ask";
35
+ }
36
+ }
37
+ function autonomyDenyRejection(level, tool, actionClass) {
38
+ return {
39
+ short: `${tool} denied: autonomy level is ${level}`,
40
+ detail: `Clio is at autonomy ${level}: ${actionClass} actions are denied without prompting. Describe the change you would make instead, so the operator can apply it or raise the autonomy level.`,
41
+ hints: ["Propose the exact edit or command as text.", "The operator can change the level in /settings."]
42
+ };
43
+ }
44
+ function autonomyAskRejection(level, tool, actionClass, exposure = DEFAULT_AUTONOMY_EXPOSURE) {
45
+ if (exposure === "outward") {
46
+ return {
47
+ short: `${tool} needs approval: outward-facing gate at autonomy ${level}`,
48
+ detail: `The call declared exposure=outward, so answering it publishes or sends something outside the workspace. Autonomy ${level} auto-answers local gates and parks outward-facing ones for the operator.`,
49
+ hints: [
50
+ "Approving resumes only this call.",
51
+ "Autonomy full-auto answers outward gates too; the safety net still applies there."
52
+ ]
53
+ };
54
+ }
55
+ return {
56
+ short: `${tool} needs approval (${actionClass}) at autonomy ${level}`,
57
+ detail: `Autonomy ${level} routes ${actionClass} actions through operator approval. The call is parked until the operator approves it once or cancels it.`,
58
+ hints: [
59
+ "Approving resumes only this call.",
60
+ "Recognized commands can be added to .clio-coder/safety.yaml.",
61
+ // The sanctioned pivots for a gated shell command: typed verification
62
+ // and read-class observe tools run without approval at this level,
63
+ // and models otherwise stall retrying denied bash for checks or
64
+ // directory listings.
65
+ ...actionClass === "execute" ? [
66
+ 'A declared package or project-catalog check runs without approval through the verify tool: verify(check="<id>").',
67
+ "Read-only inspection runs without approval through the ls, read, grep, and find tools."
68
+ ] : []
69
+ ]
70
+ };
71
+ }
72
+
73
+ export {
74
+ AUTONOMY_LEVELS,
75
+ DEFAULT_AUTONOMY_LEVEL,
76
+ isAutonomyLevel,
77
+ AUTONOMY_EXPOSURES,
78
+ DEFAULT_AUTONOMY_EXPOSURE,
79
+ mapAutonomy,
80
+ autonomyDenyRejection,
81
+ autonomyAskRejection
82
+ };
83
+ //# sourceMappingURL=chunk-HWUFFB6L.js.map