@aragon-agent/cli 0.6.47 → 0.6.48

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 (775) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +27 -6
  3. package/dist/agent/coalesce.d.ts +1 -1
  4. package/dist/agent/controller.d.ts +21 -21
  5. package/dist/agent/controller.js +13 -13
  6. package/dist/agent/conversation-reset.d.ts +1 -1
  7. package/dist/agent/governance-wiring.d.ts +6 -6
  8. package/dist/agent/governance-wiring.js +4 -4
  9. package/dist/agent/headless.d.ts +5 -5
  10. package/dist/agent/headless.js +4 -4
  11. package/dist/agent/job-notices.d.ts +1 -1
  12. package/dist/agent/job-notices.js +1 -1
  13. package/dist/agent/kit-apply.d.ts +3 -3
  14. package/dist/agent/kit-apply.js +3 -3
  15. package/dist/agent/model-profile-settings.d.ts +2 -2
  16. package/dist/agent/model-profile-settings.js +6 -6
  17. package/dist/agent/prompt-options.d.ts +1 -1
  18. package/dist/agent/system-prompt.d.ts +1 -1
  19. package/dist/{ui → app}/App.d.ts +9 -9
  20. package/dist/{ui → app}/App.js +79 -79
  21. package/dist/{ui → app}/use-startup-notices.d.ts +1 -1
  22. package/dist/{ui → app}/use-startup-notices.js +2 -2
  23. package/dist/cli.js +29 -29
  24. package/dist/commands/agents-command.js +1 -1
  25. package/dist/commands/builtins.js +9 -9
  26. package/dist/commands/governance-command.js +2 -2
  27. package/dist/commands/governance-runs-table.js +1 -1
  28. package/dist/commands/kit-command.js +1 -1
  29. package/dist/commands/perf.d.ts +3 -3
  30. package/dist/commands/perf.js +1 -1
  31. package/dist/commands/registry.d.ts +8 -8
  32. package/dist/commands/skills.js +2 -2
  33. package/dist/commands/team-command.js +1 -1
  34. package/dist/compaction/archive.d.ts +1 -1
  35. package/dist/compaction/archive.js +1 -1
  36. package/dist/compaction/child.d.ts +3 -3
  37. package/dist/compaction/child.js +4 -4
  38. package/dist/compaction/command.js +5 -5
  39. package/dist/compaction/compactor.d.ts +6 -6
  40. package/dist/compaction/compactor.js +6 -6
  41. package/dist/compaction/context-command.js +1 -1
  42. package/dist/compaction/digest.js +1 -1
  43. package/dist/compaction/memory-input.js +1 -1
  44. package/dist/compaction/memory-validation.js +1 -1
  45. package/dist/compaction/memory.js +1 -1
  46. package/dist/compaction/summarize-call.js +1 -1
  47. package/dist/compaction/summary-prompt.js +1 -1
  48. package/dist/compaction/tail-budget.js +2 -2
  49. package/dist/compaction/wiring.d.ts +5 -5
  50. package/dist/compaction/wiring.js +2 -2
  51. package/dist/config/cli-commands.d.ts +1 -1
  52. package/dist/config/cli-commands.js +3 -3
  53. package/dist/config/env.d.ts +1 -1
  54. package/dist/config/env.js +4 -4
  55. package/dist/config/load.d.ts +2 -2
  56. package/dist/config/load.js +6 -6
  57. package/dist/config/migrate-state-out-of-config.js +1 -1
  58. package/dist/config/model-profile-store.d.ts +4 -54
  59. package/dist/config/model-profile-store.js +3 -3
  60. package/dist/config/prompt-history.js +1 -1
  61. package/dist/config/store.d.ts +2 -2
  62. package/dist/config/store.js +3 -3
  63. package/dist/diagnostics/doctor.js +4 -4
  64. package/dist/exec/bridge/decisions.d.ts +1 -1
  65. package/dist/exec/bridge/human-answers.d.ts +1 -1
  66. package/dist/exec/bridge/human-answers.js +1 -1
  67. package/dist/exec/bridge/protocol.d.ts +1 -1
  68. package/dist/exec/bridge/server.js +1 -1
  69. package/dist/exec/events.d.ts +2 -2
  70. package/dist/exec/index.d.ts +1 -1
  71. package/dist/exec/index.js +1 -1
  72. package/dist/exec/permission.js +1 -1
  73. package/dist/exec/runner.d.ts +3 -3
  74. package/dist/exec/runner.js +2 -2
  75. package/dist/exec/threads/runtime.js +1 -1
  76. package/dist/fast/digest.d.ts +1 -1
  77. package/dist/fast/digest.js +1 -1
  78. package/dist/fast/frames.d.ts +1 -1
  79. package/dist/fast/frames.js +1 -1
  80. package/dist/fast/prompt.d.ts +1 -1
  81. package/dist/fast/prompt.js +1 -1
  82. package/dist/fast/review-call.js +1 -1
  83. package/dist/fast/reviewer.d.ts +3 -3
  84. package/dist/fast/reviewer.js +1 -1
  85. package/dist/fast/summary-call.d.ts +3 -3
  86. package/dist/fast/summary-call.js +2 -2
  87. package/dist/fast/summary-prompt.d.ts +1 -1
  88. package/dist/fast/summary-prompt.js +1 -1
  89. package/dist/fast/wiring.d.ts +4 -4
  90. package/dist/fast/wiring.js +1 -1
  91. package/dist/governance/card-normalize.d.ts +1 -1
  92. package/dist/governance/copy.d.ts +1 -1
  93. package/dist/governance/copy.js +2 -2
  94. package/dist/governance/engine/artifact-persist.d.ts +1 -1
  95. package/dist/governance/engine/budget.d.ts +1 -1
  96. package/dist/governance/engine/budget.js +1 -1
  97. package/dist/governance/engine/cards.d.ts +1 -1
  98. package/dist/governance/engine/digest.js +1 -1
  99. package/dist/governance/engine/engine-core.d.ts +5 -5
  100. package/dist/governance/engine/engine-core.js +1 -1
  101. package/dist/governance/engine/engine.d.ts +1 -1
  102. package/dist/governance/engine/engine.js +1 -1
  103. package/dist/governance/engine/estimate.d.ts +1 -1
  104. package/dist/governance/engine/estimate.js +1 -1
  105. package/dist/governance/engine/inspector.js +2 -2
  106. package/dist/governance/engine/integration.d.ts +1 -1
  107. package/dist/governance/engine/lifecycle.d.ts +1 -1
  108. package/dist/governance/engine/lifecycle.js +1 -1
  109. package/dist/governance/engine/phase-members.d.ts +1 -1
  110. package/dist/governance/engine/phase-planner.d.ts +1 -1
  111. package/dist/governance/engine/phase-planner.js +1 -1
  112. package/dist/governance/engine/rebuild.d.ts +1 -1
  113. package/dist/governance/engine/report.d.ts +1 -1
  114. package/dist/governance/engine/report.js +1 -1
  115. package/dist/governance/engine/run-digest.d.ts +1 -1
  116. package/dist/governance/engine/spec-builder.d.ts +2 -2
  117. package/dist/governance/engine/spec-builder.js +2 -2
  118. package/dist/governance/engine/stage-runner.js +2 -2
  119. package/dist/governance/engine/start-input.d.ts +1 -1
  120. package/dist/governance/engine/start-input.js +1 -1
  121. package/dist/governance/engine/state-machine.d.ts +1 -1
  122. package/dist/governance/engine/state-machine.js +3 -3
  123. package/dist/governance/engine/submission-queries.d.ts +1 -1
  124. package/dist/governance/engine/submission-render.d.ts +1 -1
  125. package/dist/governance/engine/submissions.d.ts +1 -1
  126. package/dist/governance/engine/submissions.js +1 -1
  127. package/dist/governance/engine/visibility.d.ts +1 -1
  128. package/dist/governance/engine/visibility.js +1 -1
  129. package/dist/governance/posture-transition.d.ts +2 -2
  130. package/dist/governance/posture-transition.js +1 -1
  131. package/dist/governance/profiles.d.ts +1 -1
  132. package/dist/governance/prompts/orchestrator-block.d.ts +2 -2
  133. package/dist/governance/prompts/orchestrator-block.js +2 -2
  134. package/dist/governance/prompts/plan-addendum.d.ts +1 -1
  135. package/dist/governance/prompts/plan-addendum.js +1 -1
  136. package/dist/governance/prompts/role-blocks.d.ts +2 -2
  137. package/dist/governance/prompts/role-blocks.js +1 -1
  138. package/dist/governance/report-reader.js +1 -1
  139. package/dist/governance/roles.d.ts +1 -1
  140. package/dist/governance/rules/claims.d.ts +1 -1
  141. package/dist/governance/rules/claims.js +1 -1
  142. package/dist/governance/rules/elimination.d.ts +1 -1
  143. package/dist/governance/rules/elimination.js +1 -1
  144. package/dist/governance/rules/failure-analysis.d.ts +2 -2
  145. package/dist/governance/rules/failure-analysis.js +1 -1
  146. package/dist/governance/rules/ledger-replay.d.ts +1 -1
  147. package/dist/governance/rules/ledger-state.d.ts +1 -1
  148. package/dist/governance/rules/ledger-state.js +1 -1
  149. package/dist/governance/rules/ledger.d.ts +2 -2
  150. package/dist/governance/rules/ledger.js +2 -2
  151. package/dist/governance/rules/rca.d.ts +1 -1
  152. package/dist/governance/rules/rca.js +1 -1
  153. package/dist/governance/rules/settlement.d.ts +2 -2
  154. package/dist/governance/rules/settlement.js +2 -2
  155. package/dist/governance/rules/suspicion.d.ts +1 -1
  156. package/dist/governance/store/artifacts.d.ts +1 -1
  157. package/dist/governance/store/artifacts.js +1 -1
  158. package/dist/governance/store/events-log.d.ts +1 -1
  159. package/dist/governance/store/run-store.d.ts +1 -1
  160. package/dist/governance/store/run-store.js +1 -1
  161. package/dist/governance/store/scoreboard-export.d.ts +1 -1
  162. package/dist/governance/tools/child-tools.d.ts +1 -1
  163. package/dist/governance/tools/guard.d.ts +1 -1
  164. package/dist/governance/tools/guard.js +1 -1
  165. package/dist/governance/tools/inspector-tools.d.ts +2 -2
  166. package/dist/governance/tools/inspector-tools.js +2 -2
  167. package/dist/governance/tools/lead-tools.d.ts +1 -1
  168. package/dist/governance/tools/lead-tools.js +1 -1
  169. package/dist/governance/tools/normalize-util.js +1 -1
  170. package/dist/governance/tools/scan-incomplete.js +1 -1
  171. package/dist/governance/tools/shared-tools.d.ts +1 -1
  172. package/dist/governance/tools/shared-tools.js +1 -1
  173. package/dist/governance/tools/submit-normalizers.d.ts +1 -1
  174. package/dist/governance/tools/submit-normalizers.js +1 -1
  175. package/dist/governance/tools/submit-tools.d.ts +1 -1
  176. package/dist/logging/cli-commands.js +1 -1
  177. package/dist/logging/install.d.ts +1 -1
  178. package/dist/logging/install.js +3 -3
  179. package/dist/logging/logger.d.ts +2 -2
  180. package/dist/logging/logger.js +31 -2
  181. package/dist/proc/kill-tree.js +1 -1
  182. package/dist/proc/log-mirror.js +1 -1
  183. package/dist/proc/log-ring.js +2 -2
  184. package/dist/proc/notices.d.ts +1 -1
  185. package/dist/proc/notices.js +2 -2
  186. package/dist/proc/prompt.d.ts +1 -1
  187. package/dist/proc/prompt.js +1 -1
  188. package/dist/proc/readiness.js +1 -1
  189. package/dist/proc/supervisor.d.ts +1 -1
  190. package/dist/proc/supervisor.js +3 -3
  191. package/dist/proc/wait.d.ts +1 -1
  192. package/dist/proc/wait.js +1 -1
  193. package/dist/prompts/command.d.ts +1 -1
  194. package/dist/prompts/command.js +1 -1
  195. package/dist/prompts/normalize.d.ts +1 -1
  196. package/dist/prompts/normalize.js +1 -1
  197. package/dist/prompts/resolve.d.ts +1 -1
  198. package/dist/prompts/store.d.ts +2 -12
  199. package/dist/prompts/store.js +6 -60
  200. package/dist/session/checkpoint.d.ts +2 -2
  201. package/dist/session/clear-archive.d.ts +2 -2
  202. package/dist/session/persist.d.ts +2 -2
  203. package/dist/session/persist.js +1 -1
  204. package/dist/session/startup-session.d.ts +2 -2
  205. package/dist/session/validate-session.js +3 -3
  206. package/dist/skills/service.d.ts +2 -2
  207. package/dist/team/bus.d.ts +1 -1
  208. package/dist/team/bus.js +1 -1
  209. package/dist/team/child-reviewer.d.ts +2 -2
  210. package/dist/team/child-reviewer.js +1 -1
  211. package/dist/team/comm-tools.js +1 -1
  212. package/dist/team/dispatch-gate.js +1 -1
  213. package/dist/team/forced-dispatch.js +1 -1
  214. package/dist/team/forced-mode.d.ts +1 -1
  215. package/dist/team/forced-prompt.d.ts +1 -1
  216. package/dist/team/forced-prompt.js +1 -1
  217. package/dist/team/normalize.d.ts +1 -1
  218. package/dist/team/normalize.js +1 -1
  219. package/dist/team/overseer.d.ts +3 -3
  220. package/dist/team/overseer.js +3 -3
  221. package/dist/team/prompt.d.ts +1 -1
  222. package/dist/team/prompt.js +1 -1
  223. package/dist/team/report.d.ts +2 -2
  224. package/dist/team/report.js +2 -2
  225. package/dist/team/retry.d.ts +1 -1
  226. package/dist/team/retry.js +1 -1
  227. package/dist/team/runtime.d.ts +4 -4
  228. package/dist/team/runtime.js +2 -2
  229. package/dist/team/settled.d.ts +2 -2
  230. package/dist/team/subagent.d.ts +4 -4
  231. package/dist/team/subagent.js +5 -5
  232. package/dist/team/task-tool.d.ts +1 -1
  233. package/dist/team/task-tool.js +1 -1
  234. package/dist/todo/normalize.d.ts +1 -1
  235. package/dist/todo/normalize.js +1 -1
  236. package/dist/todo/prompt.d.ts +1 -1
  237. package/dist/todo/prompt.js +1 -1
  238. package/dist/todo/store.d.ts +1 -1
  239. package/dist/todo/store.js +2 -2
  240. package/dist/todo/todo-tool.d.ts +1 -1
  241. package/dist/todo/todo-tool.js +2 -2
  242. package/dist/tools/bash-tool.d.ts +1 -1
  243. package/dist/tools/bash-tool.js +2 -2
  244. package/dist/tools/diff.d.ts +1 -1
  245. package/dist/tools/diff.js +1 -1
  246. package/dist/tools/file-change-store.d.ts +1 -1
  247. package/dist/tools/fs-tools.d.ts +2 -2
  248. package/dist/tools/fs-tools.js +1 -1
  249. package/dist/tools/index.d.ts +3 -3
  250. package/dist/tools/index.js +1 -1
  251. package/dist/tools/job-tools.d.ts +2 -2
  252. package/dist/tools/job-tools.js +4 -4
  253. package/dist/tools/plan-tools.d.ts +1 -1
  254. package/dist/tools/plan-tools.js +1 -1
  255. package/dist/tools/proc-tools.d.ts +1 -1
  256. package/dist/tools/proc-tools.js +2 -2
  257. package/dist/update/classify-failure.d.ts +1 -1
  258. package/dist/update/install-lock.js +1 -1
  259. package/dist/update/install-source.d.ts +1 -1
  260. package/dist/update/installer.js +2 -2
  261. package/dist/update/npm-view.d.ts +1 -1
  262. package/dist/update/npm-view.js +1 -1
  263. package/dist/update/registry.d.ts +1 -1
  264. package/dist/update/registry.js +1 -1
  265. package/dist/update/service.d.ts +2 -2
  266. package/dist/update/service.js +2 -2
  267. package/package.json +7 -7
  268. package/dist/agent/agent-mode.d.ts +0 -108
  269. package/dist/agent/agent-mode.js +0 -121
  270. package/dist/agent/entry-limits.d.ts +0 -65
  271. package/dist/agent/entry-limits.js +0 -133
  272. package/dist/agent/governance-view.d.ts +0 -40
  273. package/dist/agent/governance-view.js +0 -40
  274. package/dist/agent/invocation-card.d.ts +0 -77
  275. package/dist/agent/invocation-card.js +0 -169
  276. package/dist/agent/model-probe-limits.d.ts +0 -39
  277. package/dist/agent/model-probe-limits.js +0 -25
  278. package/dist/agent/model-probe.d.ts +0 -104
  279. package/dist/agent/model-probe.js +0 -391
  280. package/dist/agent/queued-messages.d.ts +0 -23
  281. package/dist/agent/queued-messages.js +0 -49
  282. package/dist/agent/reducer.d.ts +0 -857
  283. package/dist/agent/reducer.js +0 -1646
  284. package/dist/agent/retry-view.d.ts +0 -68
  285. package/dist/agent/retry-view.js +0 -95
  286. package/dist/agent/usage.d.ts +0 -47
  287. package/dist/agent/usage.js +0 -84
  288. package/dist/compaction/limits.d.ts +0 -61
  289. package/dist/compaction/limits.js +0 -64
  290. package/dist/compaction/meter.d.ts +0 -276
  291. package/dist/compaction/meter.js +0 -512
  292. package/dist/compaction/pressure.d.ts +0 -163
  293. package/dist/compaction/pressure.js +0 -199
  294. package/dist/compaction/reason-text.d.ts +0 -36
  295. package/dist/compaction/reason-text.js +0 -78
  296. package/dist/compaction/types.d.ts +0 -360
  297. package/dist/compaction/types.js +0 -22
  298. package/dist/config/governance-config.d.ts +0 -125
  299. package/dist/config/governance-config.js +0 -164
  300. package/dist/config/kit-resolution.d.ts +0 -93
  301. package/dist/config/kit-resolution.js +0 -226
  302. package/dist/config/model-kits.d.ts +0 -225
  303. package/dist/config/model-kits.js +0 -302
  304. package/dist/config/model-profile-resolution.d.ts +0 -28
  305. package/dist/config/model-profile-resolution.js +0 -88
  306. package/dist/config/model-profiles.d.ts +0 -103
  307. package/dist/config/model-profiles.js +0 -188
  308. package/dist/config/schema.d.ts +0 -1645
  309. package/dist/config/schema.js +0 -1383
  310. package/dist/fast/limits.d.ts +0 -152
  311. package/dist/fast/limits.js +0 -152
  312. package/dist/fast/resolve.d.ts +0 -44
  313. package/dist/fast/resolve.js +0 -107
  314. package/dist/fast/task-summary-types.d.ts +0 -66
  315. package/dist/fast/task-summary-types.js +0 -17
  316. package/dist/fast/types.d.ts +0 -141
  317. package/dist/fast/types.js +0 -14
  318. package/dist/governance/governed-dispatch.d.ts +0 -19
  319. package/dist/governance/governed-dispatch.js +0 -17
  320. package/dist/governance/limits.d.ts +0 -107
  321. package/dist/governance/limits.js +0 -131
  322. package/dist/governance/posture.d.ts +0 -35
  323. package/dist/governance/posture.js +0 -59
  324. package/dist/governance/rules/events-table.d.ts +0 -46
  325. package/dist/governance/rules/events-table.js +0 -94
  326. package/dist/governance/types.d.ts +0 -661
  327. package/dist/governance/types.js +0 -27
  328. package/dist/input/control-sequences.d.ts +0 -71
  329. package/dist/input/control-sequences.js +0 -222
  330. package/dist/input/csiu-keys.d.ts +0 -66
  331. package/dist/input/csiu-keys.js +0 -181
  332. package/dist/input/cursor-report.d.ts +0 -61
  333. package/dist/input/cursor-report.js +0 -97
  334. package/dist/input/enter-sequences.d.ts +0 -64
  335. package/dist/input/enter-sequences.js +0 -153
  336. package/dist/input/interrupt-gesture.d.ts +0 -18
  337. package/dist/input/interrupt-gesture.js +0 -19
  338. package/dist/input/keyboard-enhancement.d.ts +0 -42
  339. package/dist/input/keyboard-enhancement.js +0 -65
  340. package/dist/input/keymap.d.ts +0 -20
  341. package/dist/input/keymap.js +0 -99
  342. package/dist/input/limits.d.ts +0 -118
  343. package/dist/input/limits.js +0 -109
  344. package/dist/input/mouse-events.d.ts +0 -87
  345. package/dist/input/mouse-events.js +0 -212
  346. package/dist/input/paste-parse.d.ts +0 -83
  347. package/dist/input/paste-parse.js +0 -107
  348. package/dist/input/pointer-router.d.ts +0 -11
  349. package/dist/input/pointer-router.js +0 -14
  350. package/dist/input/stdin-filter.d.ts +0 -112
  351. package/dist/input/stdin-filter.js +0 -657
  352. package/dist/input/win32-input-mode.d.ts +0 -61
  353. package/dist/input/win32-input-mode.js +0 -269
  354. package/dist/logging/levels.d.ts +0 -40
  355. package/dist/logging/levels.js +0 -59
  356. package/dist/logging/secret-registry.d.ts +0 -32
  357. package/dist/logging/secret-registry.js +0 -73
  358. package/dist/proc/limits.d.ts +0 -214
  359. package/dist/proc/limits.js +0 -221
  360. package/dist/proc/progress.d.ts +0 -47
  361. package/dist/proc/progress.js +0 -163
  362. package/dist/proc/types.d.ts +0 -269
  363. package/dist/proc/types.js +0 -15
  364. package/dist/proc/wait-view.d.ts +0 -65
  365. package/dist/proc/wait-view.js +0 -66
  366. package/dist/prompts/copy.d.ts +0 -89
  367. package/dist/prompts/copy.js +0 -131
  368. package/dist/prompts/fill.d.ts +0 -51
  369. package/dist/prompts/fill.js +0 -46
  370. package/dist/prompts/limits.d.ts +0 -53
  371. package/dist/prompts/limits.js +0 -53
  372. package/dist/prompts/search.d.ts +0 -58
  373. package/dist/prompts/search.js +0 -146
  374. package/dist/prompts/types.d.ts +0 -204
  375. package/dist/prompts/types.js +0 -13
  376. package/dist/team/activity.d.ts +0 -67
  377. package/dist/team/activity.js +0 -130
  378. package/dist/team/limits.d.ts +0 -308
  379. package/dist/team/limits.js +0 -330
  380. package/dist/team/model.d.ts +0 -104
  381. package/dist/team/model.js +0 -150
  382. package/dist/team/panel-rows.d.ts +0 -48
  383. package/dist/team/panel-rows.js +0 -75
  384. package/dist/team/timeline.d.ts +0 -74
  385. package/dist/team/timeline.js +0 -101
  386. package/dist/team/types.d.ts +0 -354
  387. package/dist/team/types.js +0 -13
  388. package/dist/todo/acceptance.d.ts +0 -120
  389. package/dist/todo/acceptance.js +0 -399
  390. package/dist/todo/follow-through.d.ts +0 -138
  391. package/dist/todo/follow-through.js +0 -248
  392. package/dist/todo/limits.d.ts +0 -152
  393. package/dist/todo/limits.js +0 -152
  394. package/dist/todo/panel-rows.d.ts +0 -45
  395. package/dist/todo/panel-rows.js +0 -70
  396. package/dist/todo/plan-sections.d.ts +0 -60
  397. package/dist/todo/plan-sections.js +0 -108
  398. package/dist/todo/row-window.d.ts +0 -51
  399. package/dist/todo/row-window.js +0 -107
  400. package/dist/todo/types.d.ts +0 -124
  401. package/dist/todo/types.js +0 -12
  402. package/dist/tools/human-input.d.ts +0 -212
  403. package/dist/tools/human-input.js +0 -265
  404. package/dist/tools/patch.d.ts +0 -115
  405. package/dist/tools/patch.js +0 -453
  406. package/dist/tools/terminal-output.d.ts +0 -115
  407. package/dist/tools/terminal-output.js +0 -201
  408. package/dist/tools/tool-output-store.d.ts +0 -68
  409. package/dist/tools/tool-output-store.js +0 -102
  410. package/dist/ui/ActivityLine.d.ts +0 -26
  411. package/dist/ui/ActivityLine.js +0 -51
  412. package/dist/ui/AutocompletePopup.d.ts +0 -23
  413. package/dist/ui/AutocompletePopup.js +0 -17
  414. package/dist/ui/BottomStatusRow.d.ts +0 -10
  415. package/dist/ui/BottomStatusRow.js +0 -9
  416. package/dist/ui/Composer.d.ts +0 -115
  417. package/dist/ui/Composer.js +0 -64
  418. package/dist/ui/GovernancePanel.d.ts +0 -50
  419. package/dist/ui/GovernancePanel.js +0 -77
  420. package/dist/ui/GovernanceRun.d.ts +0 -18
  421. package/dist/ui/GovernanceRun.js +0 -11
  422. package/dist/ui/Header.d.ts +0 -48
  423. package/dist/ui/Header.js +0 -27
  424. package/dist/ui/Logo.d.ts +0 -32
  425. package/dist/ui/Logo.js +0 -65
  426. package/dist/ui/Markdown.d.ts +0 -29
  427. package/dist/ui/Markdown.js +0 -116
  428. package/dist/ui/PromptCaret.d.ts +0 -11
  429. package/dist/ui/PromptCaret.js +0 -31
  430. package/dist/ui/PromptInput.d.ts +0 -192
  431. package/dist/ui/PromptInput.js +0 -689
  432. package/dist/ui/QueuePanel.d.ts +0 -8
  433. package/dist/ui/QueuePanel.js +0 -9
  434. package/dist/ui/QueueStatusRow.d.ts +0 -24
  435. package/dist/ui/QueueStatusRow.js +0 -51
  436. package/dist/ui/ScrollbackShell.d.ts +0 -132
  437. package/dist/ui/ScrollbackShell.js +0 -26
  438. package/dist/ui/SessionOpener.d.ts +0 -30
  439. package/dist/ui/SessionOpener.js +0 -12
  440. package/dist/ui/StatusBar.d.ts +0 -130
  441. package/dist/ui/StatusBar.js +0 -61
  442. package/dist/ui/TeamPanel.d.ts +0 -76
  443. package/dist/ui/TeamPanel.js +0 -103
  444. package/dist/ui/ToastStack.d.ts +0 -8
  445. package/dist/ui/ToastStack.js +0 -31
  446. package/dist/ui/TodoPanel.d.ts +0 -52
  447. package/dist/ui/TodoPanel.js +0 -214
  448. package/dist/ui/Transcript.d.ts +0 -105
  449. package/dist/ui/Transcript.js +0 -258
  450. package/dist/ui/UpdateLine.d.ts +0 -44
  451. package/dist/ui/UpdateLine.js +0 -129
  452. package/dist/ui/activity-phrases.d.ts +0 -33
  453. package/dist/ui/activity-phrases.js +0 -50
  454. package/dist/ui/capabilities.d.ts +0 -27
  455. package/dist/ui/capabilities.js +0 -65
  456. package/dist/ui/clipboard-task.d.ts +0 -29
  457. package/dist/ui/clipboard-task.js +0 -66
  458. package/dist/ui/clipboard.d.ts +0 -31
  459. package/dist/ui/clipboard.js +0 -157
  460. package/dist/ui/color-runtime.d.ts +0 -5
  461. package/dist/ui/color-runtime.js +0 -29
  462. package/dist/ui/composer-input.d.ts +0 -38
  463. package/dist/ui/composer-input.js +0 -79
  464. package/dist/ui/composer-limits.d.ts +0 -30
  465. package/dist/ui/composer-limits.js +0 -45
  466. package/dist/ui/composer-rows.d.ts +0 -73
  467. package/dist/ui/composer-rows.js +0 -129
  468. package/dist/ui/console-bridge.d.ts +0 -19
  469. package/dist/ui/console-bridge.js +0 -52
  470. package/dist/ui/density.d.ts +0 -26
  471. package/dist/ui/density.js +0 -34
  472. package/dist/ui/display-tab.d.ts +0 -51
  473. package/dist/ui/display-tab.js +0 -82
  474. package/dist/ui/editor-navigation.d.ts +0 -55
  475. package/dist/ui/editor-navigation.js +0 -96
  476. package/dist/ui/editor-reducer.d.ts +0 -108
  477. package/dist/ui/editor-reducer.js +0 -187
  478. package/dist/ui/enter-frames.d.ts +0 -47
  479. package/dist/ui/enter-frames.js +0 -117
  480. package/dist/ui/entries/AssistantEntry.d.ts +0 -37
  481. package/dist/ui/entries/AssistantEntry.js +0 -43
  482. package/dist/ui/entries/CompactionCard.d.ts +0 -88
  483. package/dist/ui/entries/CompactionCard.js +0 -222
  484. package/dist/ui/entries/DiffView.d.ts +0 -61
  485. package/dist/ui/entries/DiffView.js +0 -103
  486. package/dist/ui/entries/EntryFrame.d.ts +0 -23
  487. package/dist/ui/entries/EntryFrame.js +0 -6
  488. package/dist/ui/entries/FastCard.d.ts +0 -53
  489. package/dist/ui/entries/FastCard.js +0 -105
  490. package/dist/ui/entries/GovernanceCard.d.ts +0 -30
  491. package/dist/ui/entries/GovernanceCard.js +0 -32
  492. package/dist/ui/entries/InvocationCard.d.ts +0 -20
  493. package/dist/ui/entries/InvocationCard.js +0 -32
  494. package/dist/ui/entries/QueuedEntry.d.ts +0 -27
  495. package/dist/ui/entries/QueuedEntry.js +0 -33
  496. package/dist/ui/entries/RetryCard.d.ts +0 -56
  497. package/dist/ui/entries/RetryCard.js +0 -60
  498. package/dist/ui/entries/ServiceCard.d.ts +0 -82
  499. package/dist/ui/entries/ServiceCard.js +0 -151
  500. package/dist/ui/entries/TeamCard.d.ts +0 -55
  501. package/dist/ui/entries/TeamCard.js +0 -94
  502. package/dist/ui/entries/TodoCard.d.ts +0 -54
  503. package/dist/ui/entries/TodoCard.js +0 -98
  504. package/dist/ui/entries/ToolCard.d.ts +0 -81
  505. package/dist/ui/entries/ToolCard.js +0 -169
  506. package/dist/ui/entries/ToolPreview.d.ts +0 -59
  507. package/dist/ui/entries/ToolPreview.js +0 -208
  508. package/dist/ui/entries/UserEntry.d.ts +0 -36
  509. package/dist/ui/entries/UserEntry.js +0 -57
  510. package/dist/ui/entries/WaitCard.d.ts +0 -37
  511. package/dist/ui/entries/WaitCard.js +0 -92
  512. package/dist/ui/exit-snapshot.d.ts +0 -43
  513. package/dist/ui/exit-snapshot.js +0 -26
  514. package/dist/ui/frame-differ.d.ts +0 -166
  515. package/dist/ui/frame-differ.js +0 -354
  516. package/dist/ui/frame-observer.d.ts +0 -17
  517. package/dist/ui/frame-observer.js +0 -94
  518. package/dist/ui/frame-parser.d.ts +0 -7
  519. package/dist/ui/frame-parser.js +0 -18
  520. package/dist/ui/gauge.d.ts +0 -39
  521. package/dist/ui/gauge.js +0 -55
  522. package/dist/ui/glyphs.d.ts +0 -178
  523. package/dist/ui/glyphs.js +0 -165
  524. package/dist/ui/governance-copy.d.ts +0 -69
  525. package/dist/ui/governance-copy.js +0 -104
  526. package/dist/ui/governance-status.d.ts +0 -145
  527. package/dist/ui/governance-status.js +0 -326
  528. package/dist/ui/gradient.d.ts +0 -11
  529. package/dist/ui/gradient.js +0 -50
  530. package/dist/ui/ink-runtime.d.ts +0 -4
  531. package/dist/ui/ink-runtime.js +0 -51
  532. package/dist/ui/interaction-copy.d.ts +0 -84
  533. package/dist/ui/interaction-copy.js +0 -41
  534. package/dist/ui/interaction-hints.d.ts +0 -44
  535. package/dist/ui/interaction-hints.js +0 -97
  536. package/dist/ui/layout/AppShell.d.ts +0 -17
  537. package/dist/ui/layout/AppShell.js +0 -6
  538. package/dist/ui/layout/Gutter.d.ts +0 -67
  539. package/dist/ui/layout/Gutter.js +0 -42
  540. package/dist/ui/layout/MeasuredEntry.d.ts +0 -21
  541. package/dist/ui/layout/MeasuredEntry.js +0 -30
  542. package/dist/ui/layout/OverlayFrame.d.ts +0 -73
  543. package/dist/ui/layout/OverlayFrame.js +0 -110
  544. package/dist/ui/layout/ScrollIndicator.d.ts +0 -32
  545. package/dist/ui/layout/ScrollIndicator.js +0 -22
  546. package/dist/ui/layout/ScrollViewport.d.ts +0 -40
  547. package/dist/ui/layout/ScrollViewport.js +0 -222
  548. package/dist/ui/layout/agents-board.d.ts +0 -102
  549. package/dist/ui/layout/agents-board.js +0 -389
  550. package/dist/ui/layout/autocomplete.d.ts +0 -18
  551. package/dist/ui/layout/autocomplete.js +0 -26
  552. package/dist/ui/layout/budget.d.ts +0 -43
  553. package/dist/ui/layout/budget.js +0 -52
  554. package/dist/ui/layout/cells.d.ts +0 -61
  555. package/dist/ui/layout/cells.js +0 -156
  556. package/dist/ui/layout/document-layout.d.ts +0 -13
  557. package/dist/ui/layout/document-layout.js +0 -10
  558. package/dist/ui/layout/follow-state.d.ts +0 -138
  559. package/dist/ui/layout/follow-state.js +0 -148
  560. package/dist/ui/layout/frame.d.ts +0 -36
  561. package/dist/ui/layout/frame.js +0 -39
  562. package/dist/ui/layout/governance-board.d.ts +0 -121
  563. package/dist/ui/layout/governance-board.js +0 -382
  564. package/dist/ui/layout/governance-card.d.ts +0 -53
  565. package/dist/ui/layout/governance-card.js +0 -134
  566. package/dist/ui/layout/governance-chip.d.ts +0 -38
  567. package/dist/ui/layout/governance-chip.js +0 -64
  568. package/dist/ui/layout/governance-panel.d.ts +0 -85
  569. package/dist/ui/layout/governance-panel.js +0 -358
  570. package/dist/ui/layout/governance-roster.d.ts +0 -65
  571. package/dist/ui/layout/governance-roster.js +0 -275
  572. package/dist/ui/layout/header-hints.d.ts +0 -90
  573. package/dist/ui/layout/header-hints.js +0 -110
  574. package/dist/ui/layout/header-left.d.ts +0 -115
  575. package/dist/ui/layout/header-left.js +0 -206
  576. package/dist/ui/layout/invocation-card.d.ts +0 -41
  577. package/dist/ui/layout/invocation-card.js +0 -91
  578. package/dist/ui/layout/kit-chip.d.ts +0 -50
  579. package/dist/ui/layout/kit-chip.js +0 -81
  580. package/dist/ui/layout/overlay-window.d.ts +0 -43
  581. package/dist/ui/layout/overlay-window.js +0 -51
  582. package/dist/ui/layout/queue-layout.d.ts +0 -19
  583. package/dist/ui/layout/queue-layout.js +0 -26
  584. package/dist/ui/layout/rail.d.ts +0 -7
  585. package/dist/ui/layout/rail.js +0 -16
  586. package/dist/ui/layout/scroll-indicator.d.ts +0 -27
  587. package/dist/ui/layout/scroll-indicator.js +0 -36
  588. package/dist/ui/layout/scroll.d.ts +0 -37
  589. package/dist/ui/layout/scroll.js +0 -99
  590. package/dist/ui/layout/scrollbar-geometry.d.ts +0 -17
  591. package/dist/ui/layout/scrollbar-geometry.js +0 -13
  592. package/dist/ui/layout/session-chip.d.ts +0 -52
  593. package/dist/ui/layout/session-chip.js +0 -64
  594. package/dist/ui/layout/shortcut-panel-layout.d.ts +0 -191
  595. package/dist/ui/layout/shortcut-panel-layout.js +0 -321
  596. package/dist/ui/layout/status-detail-layout.d.ts +0 -9
  597. package/dist/ui/layout/status-detail-layout.js +0 -79
  598. package/dist/ui/layout/status-layout.d.ts +0 -140
  599. package/dist/ui/layout/status-layout.js +0 -262
  600. package/dist/ui/layout/task-summary-cell.d.ts +0 -61
  601. package/dist/ui/layout/task-summary-cell.js +0 -65
  602. package/dist/ui/layout/team-panel.d.ts +0 -18
  603. package/dist/ui/layout/team-panel.js +0 -25
  604. package/dist/ui/layout/team-row.d.ts +0 -139
  605. package/dist/ui/layout/team-row.js +0 -246
  606. package/dist/ui/layout/todo-layout.d.ts +0 -62
  607. package/dist/ui/layout/todo-layout.js +0 -102
  608. package/dist/ui/layout/useTerminalSize.d.ts +0 -13
  609. package/dist/ui/layout/useTerminalSize.js +0 -50
  610. package/dist/ui/layout/viewport-geometry.d.ts +0 -29
  611. package/dist/ui/layout/viewport-geometry.js +0 -28
  612. package/dist/ui/layout/virtual-window.d.ts +0 -112
  613. package/dist/ui/layout/virtual-window.js +0 -494
  614. package/dist/ui/layout/wait-bar.d.ts +0 -34
  615. package/dist/ui/layout/wait-bar.js +0 -48
  616. package/dist/ui/layout/wrap-rows.d.ts +0 -26
  617. package/dist/ui/layout/wrap-rows.js +0 -88
  618. package/dist/ui/live-clamp.d.ts +0 -14
  619. package/dist/ui/live-clamp.js +0 -46
  620. package/dist/ui/markdown-blocks.d.ts +0 -107
  621. package/dist/ui/markdown-blocks.js +0 -240
  622. package/dist/ui/overlays/AgentsBoardOverlay.d.ts +0 -57
  623. package/dist/ui/overlays/AgentsBoardOverlay.js +0 -183
  624. package/dist/ui/overlays/ConfirmDialog.d.ts +0 -31
  625. package/dist/ui/overlays/ConfirmDialog.js +0 -44
  626. package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +0 -41
  627. package/dist/ui/overlays/GovernanceBoardOverlay.js +0 -76
  628. package/dist/ui/overlays/GovernanceSettingsPage.d.ts +0 -48
  629. package/dist/ui/overlays/GovernanceSettingsPage.js +0 -93
  630. package/dist/ui/overlays/HelpOverlay.d.ts +0 -29
  631. package/dist/ui/overlays/HelpOverlay.js +0 -232
  632. package/dist/ui/overlays/KitEditor.d.ts +0 -23
  633. package/dist/ui/overlays/KitEditor.js +0 -101
  634. package/dist/ui/overlays/KitManager.d.ts +0 -23
  635. package/dist/ui/overlays/KitManager.js +0 -104
  636. package/dist/ui/overlays/KitPicker.d.ts +0 -49
  637. package/dist/ui/overlays/KitPicker.js +0 -58
  638. package/dist/ui/overlays/ModelDiscoveryList.d.ts +0 -23
  639. package/dist/ui/overlays/ModelDiscoveryList.js +0 -161
  640. package/dist/ui/overlays/ModelPicker.d.ts +0 -26
  641. package/dist/ui/overlays/ModelPicker.js +0 -63
  642. package/dist/ui/overlays/ModelProfileEditor.d.ts +0 -29
  643. package/dist/ui/overlays/ModelProfileEditor.js +0 -168
  644. package/dist/ui/overlays/ModelProfilePicker.d.ts +0 -48
  645. package/dist/ui/overlays/ModelProfilePicker.js +0 -231
  646. package/dist/ui/overlays/PlanReviewOverlay.d.ts +0 -51
  647. package/dist/ui/overlays/PlanReviewOverlay.js +0 -132
  648. package/dist/ui/overlays/PromptEditorPage.d.ts +0 -48
  649. package/dist/ui/overlays/PromptEditorPage.js +0 -227
  650. package/dist/ui/overlays/PromptLibraryOverlay.d.ts +0 -37
  651. package/dist/ui/overlays/PromptLibraryOverlay.js +0 -191
  652. package/dist/ui/overlays/PromptPicker.d.ts +0 -36
  653. package/dist/ui/overlays/PromptPicker.js +0 -129
  654. package/dist/ui/overlays/PromptTextArea.d.ts +0 -86
  655. package/dist/ui/overlays/PromptTextArea.js +0 -141
  656. package/dist/ui/overlays/QuestionOverlay.d.ts +0 -39
  657. package/dist/ui/overlays/QuestionOverlay.js +0 -258
  658. package/dist/ui/overlays/QueueOverlay.d.ts +0 -22
  659. package/dist/ui/overlays/QueueOverlay.js +0 -79
  660. package/dist/ui/overlays/SettingsScreen.d.ts +0 -228
  661. package/dist/ui/overlays/SettingsScreen.js +0 -1037
  662. package/dist/ui/overlays/ShortcutPanel.d.ts +0 -39
  663. package/dist/ui/overlays/ShortcutPanel.js +0 -106
  664. package/dist/ui/overlays/TeamFanoutPage.d.ts +0 -51
  665. package/dist/ui/overlays/TeamFanoutPage.js +0 -90
  666. package/dist/ui/overlays/governance-settings.d.ts +0 -79
  667. package/dist/ui/overlays/governance-settings.js +0 -140
  668. package/dist/ui/overlays/kit-picker-state.d.ts +0 -87
  669. package/dist/ui/overlays/kit-picker-state.js +0 -136
  670. package/dist/ui/overlays/kit-settings-state.d.ts +0 -129
  671. package/dist/ui/overlays/kit-settings-state.js +0 -268
  672. package/dist/ui/overlays/model-probe-view.d.ts +0 -128
  673. package/dist/ui/overlays/model-probe-view.js +0 -225
  674. package/dist/ui/overlays/model-profile-state.d.ts +0 -177
  675. package/dist/ui/overlays/model-profile-state.js +0 -301
  676. package/dist/ui/overlays/prompt-library-state.d.ts +0 -162
  677. package/dist/ui/overlays/prompt-library-state.js +0 -335
  678. package/dist/ui/overlays/prompt-picker-state.d.ts +0 -71
  679. package/dist/ui/overlays/prompt-picker-state.js +0 -98
  680. package/dist/ui/overlays/team-fanout-state.d.ts +0 -106
  681. package/dist/ui/overlays/team-fanout-state.js +0 -155
  682. package/dist/ui/overlays/use-model-probe.d.ts +0 -30
  683. package/dist/ui/overlays/use-model-probe.js +0 -109
  684. package/dist/ui/palettes.d.ts +0 -112
  685. package/dist/ui/palettes.js +0 -130
  686. package/dist/ui/paste-frames.d.ts +0 -91
  687. package/dist/ui/paste-frames.js +0 -117
  688. package/dist/ui/paste-tokens.d.ts +0 -90
  689. package/dist/ui/paste-tokens.js +0 -147
  690. package/dist/ui/render-cache.d.ts +0 -81
  691. package/dist/ui/render-cache.js +0 -196
  692. package/dist/ui/render-governor.d.ts +0 -54
  693. package/dist/ui/render-governor.js +0 -78
  694. package/dist/ui/run-metrics.d.ts +0 -23
  695. package/dist/ui/run-metrics.js +0 -27
  696. package/dist/ui/run-status-row.d.ts +0 -63
  697. package/dist/ui/run-status-row.js +0 -54
  698. package/dist/ui/screen.d.ts +0 -107
  699. package/dist/ui/screen.js +0 -234
  700. package/dist/ui/scrollback/LiveTail.d.ts +0 -115
  701. package/dist/ui/scrollback/LiveTail.js +0 -48
  702. package/dist/ui/scrollback/band.d.ts +0 -114
  703. package/dist/ui/scrollback/band.js +0 -143
  704. package/dist/ui/scrollback/budget.d.ts +0 -90
  705. package/dist/ui/scrollback/budget.js +0 -100
  706. package/dist/ui/scrollback/canvas.d.ts +0 -100
  707. package/dist/ui/scrollback/canvas.js +0 -114
  708. package/dist/ui/scrollback/cursor-probe.d.ts +0 -71
  709. package/dist/ui/scrollback/cursor-probe.js +0 -133
  710. package/dist/ui/scrollback/drain.d.ts +0 -32
  711. package/dist/ui/scrollback/drain.js +0 -64
  712. package/dist/ui/scrollback/exit-summary.d.ts +0 -23
  713. package/dist/ui/scrollback/exit-summary.js +0 -25
  714. package/dist/ui/scrollback/limits.d.ts +0 -98
  715. package/dist/ui/scrollback/limits.js +0 -98
  716. package/dist/ui/scrollback/live-preview.d.ts +0 -34
  717. package/dist/ui/scrollback/live-preview.js +0 -130
  718. package/dist/ui/scrollback/overflow-print.d.ts +0 -108
  719. package/dist/ui/scrollback/overflow-print.js +0 -120
  720. package/dist/ui/scrollback/renderer.d.ts +0 -48
  721. package/dist/ui/scrollback/renderer.js +0 -186
  722. package/dist/ui/scrollback/scrollback-writer.d.ts +0 -174
  723. package/dist/ui/scrollback/scrollback-writer.js +0 -648
  724. package/dist/ui/scrollback/settled-boundary.d.ts +0 -42
  725. package/dist/ui/scrollback/settled-boundary.js +0 -109
  726. package/dist/ui/scrollback/tail-anchor.d.ts +0 -71
  727. package/dist/ui/scrollback/tail-anchor.js +0 -79
  728. package/dist/ui/scrollback/tail-window.d.ts +0 -73
  729. package/dist/ui/scrollback/tail-window.js +0 -89
  730. package/dist/ui/scrollback/use-scrollback-view.d.ts +0 -139
  731. package/dist/ui/scrollback/use-scrollback-view.js +0 -601
  732. package/dist/ui/scrollback/writer-shapes.d.ts +0 -127
  733. package/dist/ui/scrollback/writer-shapes.js +0 -159
  734. package/dist/ui/scrollbar-controller.d.ts +0 -30
  735. package/dist/ui/scrollbar-controller.js +0 -124
  736. package/dist/ui/selection/highlight.d.ts +0 -39
  737. package/dist/ui/selection/highlight.js +0 -64
  738. package/dist/ui/selection/screen-mirror.d.ts +0 -24
  739. package/dist/ui/selection/screen-mirror.js +0 -35
  740. package/dist/ui/selection/selection-controller.d.ts +0 -104
  741. package/dist/ui/selection/selection-controller.js +0 -372
  742. package/dist/ui/selection/selection.d.ts +0 -90
  743. package/dist/ui/selection/selection.js +0 -223
  744. package/dist/ui/shortcuts.d.ts +0 -81
  745. package/dist/ui/shortcuts.js +0 -221
  746. package/dist/ui/status-feedback.d.ts +0 -35
  747. package/dist/ui/status-feedback.js +0 -38
  748. package/dist/ui/stdout-frame-writer.d.ts +0 -74
  749. package/dist/ui/stdout-frame-writer.js +0 -155
  750. package/dist/ui/team-status.d.ts +0 -166
  751. package/dist/ui/team-status.js +0 -252
  752. package/dist/ui/terminal-plan.d.ts +0 -52
  753. package/dist/ui/terminal-plan.js +0 -49
  754. package/dist/ui/theme.d.ts +0 -96
  755. package/dist/ui/theme.js +0 -130
  756. package/dist/ui/transcript-text.d.ts +0 -41
  757. package/dist/ui/transcript-text.js +0 -282
  758. package/dist/ui/use-height-store.d.ts +0 -31
  759. package/dist/ui/use-height-store.js +0 -76
  760. package/dist/ui/use-render-governor.d.ts +0 -39
  761. package/dist/ui/use-render-governor.js +0 -57
  762. package/dist/ui/use-wheel-routing.d.ts +0 -57
  763. package/dist/ui/use-wheel-routing.js +0 -152
  764. package/dist/ui/win-vt-force.d.ts +0 -136
  765. package/dist/ui/win-vt-force.js +0 -237
  766. package/dist/ui/win-vt-input.d.ts +0 -57
  767. package/dist/ui/win-vt-input.js +0 -62
  768. package/dist/update/limits.d.ts +0 -111
  769. package/dist/update/limits.js +0 -111
  770. package/dist/update/semver.d.ts +0 -89
  771. package/dist/update/semver.js +0 -295
  772. package/dist/update/types.d.ts +0 -169
  773. package/dist/update/types.js +0 -68
  774. /package/dist/{ui → app}/session-bridge.d.ts +0 -0
  775. /package/dist/{ui → app}/session-bridge.js +0 -0
@@ -1,1037 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- * Settings screen — edit provider / model / base URL / thinking / max tokens /
4
- * API key for the active provider (spec §3.5 / §5.2). Up/Down move between
5
- * fields; Left/Right cycle enum fields; typing edits text/secret fields;
6
- * Enter saves; Esc (handled by the App) closes without saving.
7
- *
8
- * The API key is never printed: it renders as dots while editing and masked
9
- * otherwise.
10
- */
11
- import { useEffect, useReducer, useRef, useState } from 'react';
12
- import { Text, useInput } from 'ink';
13
- import { DEFAULT_MAX_OUTPUT_TOKENS, resolveOutputTokens, } from '@aragon-agent/core';
14
- import { ADAPTER_PROVIDERS, THINKING_LEVELS, maskSecret, parseContextWindowInput, parseMaxTokensInput, parseThresholdInput, } from '../../config/schema.js';
15
- import { LOG_LEVEL_NAMES } from '../../logging/levels.js';
16
- import { pickGlyphs } from '../glyphs.js';
17
- import { OverlayFrame } from '../layout/OverlayFrame.js';
18
- import { stripPasteFrames } from '../paste-frames.js';
19
- import { stripEnterFrames } from '../enter-frames.js';
20
- import { emptyModelProfiles } from '../../config/model-profiles.js';
21
- import { registerSecret } from '../../logging/secret-registry.js';
22
- import { ModelProfilePicker, useProfileScroll } from './ModelProfilePicker.js';
23
- import { ModelProfileEditor } from './ModelProfileEditor.js';
24
- import { ModelDiscoveryList } from './ModelDiscoveryList.js';
25
- import { useModelProbe } from './use-model-probe.js';
26
- import { canProbe, editorProbeTarget, visibleProbeViews } from './model-probe-view.js';
27
- import { createModelProfileState, createCustomProfile, modelProfileReducer, profileUsers, draftTeam, draftSubagentProfileId, subagentModelSummary, subagentSelectedId, SUBAGENT_FAST_ROW_ID } from './model-profile-state.js';
28
- import { KitEditor } from './KitEditor.js';
29
- import { KitManager } from './KitManager.js';
30
- import { TeamFanoutPage } from './TeamFanoutPage.js';
31
- import { fanoutRows, teamFanoutValues, teamSummary } from './team-fanout-state.js';
32
- import { GovernanceSettingsPage } from './GovernanceSettingsPage.js';
33
- import { draftGovernance, governanceRestartNote, governanceSettingRows, governanceSummary, } from './governance-settings.js';
34
- import { heldSlots, kitManagerRows, kitPackRow, kitReducer } from './kit-settings-state.js';
35
- /**
36
- * THE ROOT PAGE'S ROW INDEXES, AS NAMES (subagent-model V-5).
37
- *
38
- * Five offset sites used to agree by accident on the number 3; the Subagent
39
- * model row moves every one of them. Each site below now cites its constant,
40
- * so adding a row later is a one-line change instead of a silent regression
41
- * that focuses an error message on the wrong field.
42
- *
43
- * DERIVED FROM ONE LIST (agent-model-kits §4.5), because the kit row is the
44
- * fifth of these and the "five offsets agreed by accident" defect does not need
45
- * a sequel. Order here IS the render order.
46
- */
47
- const ROOT_ROWS = ['main', 'fast', 'subagent', 'team', 'governance', 'kit', 'manage'];
48
- const ROOT_MAIN = ROOT_ROWS.indexOf('main');
49
- const ROOT_FAST = ROOT_ROWS.indexOf('fast');
50
- const ROOT_SUBAGENT = ROOT_ROWS.indexOf('subagent');
51
- // The fan-out page (subagent-fanout D-5). It is FOURTH, directly under the model
52
- // row it complements: "which model children run on" and "how many children" are
53
- // one decision, and splitting them across the page would make the pair harder to
54
- // keep consistent than the pair of numbers inside it.
55
- const ROOT_TEAM = ROOT_ROWS.indexOf('team');
56
- // Governance (governance-mode-v1-1 5.2) sits right under Team: both decide the SHAPE of the
57
- // team, and the row is an index into this list like every other, never a typed number.
58
- const ROOT_GOVERNANCE = ROOT_ROWS.indexOf('governance');
59
- const ROOT_KIT = ROOT_ROWS.indexOf('kit');
60
- const ROOT_MANAGE = ROOT_ROWS.indexOf('manage');
61
- const ROOT_FIRST_FIELD = ROOT_ROWS.length;
62
- /** Stand-in target while no editor exists; no probe row is rendered then. */
63
- const NO_PROFILE_TARGET = { provider: '', model: '', baseUrl: null,
64
- apiKey: null };
65
- const SHOW_THINKING_OPTIONS = ['off', 'on'];
66
- const LIVE_OUTPUT_OPTIONS = ['off', 'on'];
67
- const FAST_ENABLED_OPTIONS = ['off', 'on'];
68
- const COMPACTION_ENABLED_OPTIONS = ['off', 'on'];
69
- /**
70
- * `(inherit)` IS THE EMPTY STRING, rendered as a word.
71
- *
72
- * An empty enum cell would read as "unset and therefore broken"; the truth is
73
- * that an empty `fast.provider` INHERITS the main provider, which is the setting
74
- * most users want and the one they should not have to type (§3.2 rule 2).
75
- */
76
- const FAST_INHERIT_PROVIDER = '(inherit)';
77
- const FAST_PROVIDER_OPTIONS = [FAST_INHERIT_PROVIDER, ...ADAPTER_PROVIDERS];
78
- /**
79
- * The derived, non-editable line under the five fast rows — the sibling of
80
- * `effectiveCapLine`, and it exists for the same reason (§4.5).
81
- *
82
- * A SETTINGS SCREEN THAT LETS A USER SWITCH A TIER ON AND GIVES NO SIGNAL THAT
83
- * IT CANNOT RESOLVE is the failure `effectiveCapLine` was added to fix for
84
- * `maxTokens`, one screen later. `keyFor` is the same resolver the controller
85
- * uses, so this line and the runtime cannot disagree.
86
- *
87
- * IT DOES NOT TAKE `fastReviewBudget` AND MUST NOT (§4.4 part 5): this line
88
- * describes what the tier IS, not what it is allowed to spend.
89
- */
90
- export function fastTierLine(values, hasKey) {
91
- if (values.fastEnabled !== 'on')
92
- return 'Fast tier: off';
93
- const model = values.fastModel.trim();
94
- if (model.length === 0)
95
- return 'Fast tier: off (fast.model is not set)';
96
- const provider = values.fastProvider === FAST_INHERIT_PROVIDER || values.fastProvider.trim().length === 0
97
- ? values.provider
98
- : values.fastProvider;
99
- if (!hasKey(provider)) {
100
- return `Fast tier: ${provider}:${model} (no API key for ${provider} - the tier will stay off)`;
101
- }
102
- const review = values.fastReview.trim().toLowerCase();
103
- const cadence = review === 'off'
104
- ? 'review off'
105
- : /^\d+$/.test(review)
106
- ? `review every ${review} turns`
107
- : 'review every 5 turns';
108
- return `Fast tier: ${provider}:${model} (key set) ${cadence}`;
109
- }
110
- /**
111
- * The five editable fast rows, as a config patch (§4.5 / hardening §4.4).
112
- *
113
- * PURE AND EXPORTED so `App`'s save handler holds no parsing of its own, and so
114
- * the round trip `fastSettingsFrom(config)` -> edit -> `readFastSettings` can be
115
- * tested without a terminal.
116
- *
117
- * A TYPO IN `fastReview` CHANGES NOTHING — the `review` / `reviewEveryTurns`
118
- * keys are simply omitted from the patch, so `clampFastConfig`'s merge keeps
119
- * whatever was there. That is the `Max tokens` discipline this screen already
120
- * follows, and the alternative (resolving a typo to the default) silently
121
- * discards the cadence the user actually set. `fastReviewBudget` follows the
122
- * same rule; an out-of-range NUMBER is passed through to `clampFastConfig`'s
123
- * `REVIEW_SESSION_RANGE` rather than being validated a second time here, so a
124
- * row edit and a hand-edited `config.json` land on the same value.
125
- */
126
- export function readFastSettings(values) {
127
- const review = values.fastReview.trim().toLowerCase();
128
- const parsed = /^\d+$/.test(review) ? Number.parseInt(review, 10) : Number.NaN;
129
- const budget = values.fastReviewBudget.trim();
130
- const parsedBudget = /^\d+$/.test(budget) ? Number.parseInt(budget, 10) : Number.NaN;
131
- return {
132
- enabled: values.fastEnabled === 'on',
133
- model: values.fastModel.trim(),
134
- provider: values.fastProvider === FAST_INHERIT_PROVIDER ? '' : values.fastProvider.trim(),
135
- ...(review === 'off' ? { review: false } : {}),
136
- ...(Number.isFinite(parsed) && parsed > 0
137
- ? { review: true, reviewEveryTurns: parsed }
138
- : {}),
139
- ...(Number.isFinite(parsedBudget) ? { reviewMaxPerSession: parsedBudget } : {}),
140
- };
141
- }
142
- /**
143
- * The inverse: seed the five rows from a resolved config.
144
- *
145
- * OMITTING A KEY HERE IS THE SILENT HALF OF ADDING A ROW (§4.4 part 4): the row
146
- * renders empty, `readFastSettings` sees an unparseable value, and an untouched
147
- * save writes the clamp's default over whatever the user had.
148
- */
149
- export function fastSettingsFrom(fast) {
150
- return {
151
- fastEnabled: fast.enabled ? 'on' : 'off',
152
- fastModel: fast.model,
153
- fastProvider: fast.provider.trim().length > 0 ? fast.provider : FAST_INHERIT_PROVIDER,
154
- fastReview: fast.review ? String(fast.reviewEveryTurns) : 'off',
155
- fastReviewBudget: String(fast.reviewMaxPerSession),
156
- };
157
- }
158
- /**
159
- * Read the three compaction rows back into a config patch.
160
- *
161
- * A TYPO CHANGES NOTHING — the discipline `readFastSettings` states one function
162
- * up, and the reason is the same: a threshold that silently resolved to the
163
- * default on a mistyped keystroke would be a setting the user believes they
164
- * changed and did not. `parseThresholdInput` returns `null` for anything that is
165
- * not a ratio or a percentage, and the key is then simply absent from the patch.
166
- */
167
- export function readCompactionSettings(values) {
168
- const threshold = parseThresholdInput(values.compactionThreshold);
169
- const keep = values.compactionKeepTurns.trim();
170
- const parsedKeep = /^\d+$/.test(keep) ? Number.parseInt(keep, 10) : Number.NaN;
171
- return {
172
- enabled: values.compactionEnabled === 'on',
173
- ...(threshold !== null ? { threshold } : {}),
174
- ...(Number.isFinite(parsedKeep) && parsedKeep > 0 ? { keepRecentTurns: parsedKeep } : {}),
175
- // AN ENUM ROW CANNOT BE MISTYPED, so unlike the two text rows above these are
176
- // written unconditionally.
177
- subagents: values.compactionSubagents === 'on',
178
- archive: values.compactionArchive === 'on',
179
- };
180
- }
181
- /**
182
- * The inverse: seed the three rows from a resolved config.
183
- *
184
- * OMITTING A KEY HERE IS THE SILENT HALF OF ADDING A ROW, exactly as it is for
185
- * the fast rows above: the row renders empty, `readCompactionSettings` sees an
186
- * unparseable value, and an untouched save writes the clamp's default over
187
- * whatever the user had.
188
- */
189
- export function compactionSettingsFrom(compaction) {
190
- return {
191
- compactionEnabled: compaction.enabled ? 'on' : 'off',
192
- // A PERCENTAGE, because that is the unit the status bar shows and the unit a
193
- // user thinks in. `parseThresholdInput` accepts it back.
194
- compactionThreshold: String(Math.round(compaction.threshold * 100)),
195
- compactionKeepTurns: String(compaction.keepRecentTurns),
196
- compactionSubagents: compaction.subagents ? 'on' : 'off',
197
- compactionArchive: compaction.archive ? 'on' : 'off',
198
- };
199
- }
200
- const FIELDS = [
201
- { key: 'provider', label: 'Provider', kind: 'enum', options: ADAPTER_PROVIDERS },
202
- { key: 'model', label: 'Model', kind: 'text' },
203
- { key: 'baseUrl', label: 'Base URL', kind: 'text' },
204
- { key: 'thinkingLevel', label: 'Thinking', kind: 'enum', options: THINKING_LEVELS },
205
- // Directly under `Thinking`, so the effort setting and the display setting are
206
- // read together. `Show thinking` is 13 characters, inside the 18-column label
207
- // budget `.padEnd(18)` enforces below and that IF-H7 records as silently
208
- // overflowing.
209
- { key: 'showThinking', label: 'Show thinking', kind: 'enum', options: SHOW_THINKING_OPTIONS },
210
- // Beside `Show thinking`, because the two are the transcript's only display
211
- // switches. `Live output` is 11 characters, inside the 18-column label budget
212
- // `.padEnd(18)` enforces below and that IF-H7 records as silently overflowing.
213
- { key: 'liveToolOutput', label: 'Live output', kind: 'enum', options: LIVE_OUTPUT_OPTIONS },
214
- { key: 'maxTokens', label: 'Max tokens', kind: 'text' },
215
- // DIRECTLY UNDER `Max tokens`: the two token rows read together. `Context
216
- // window` is 14 characters, inside the 18-column label budget `.padEnd(18)`
217
- // enforces below (IF-H7). Only ever RENDERED while Main is unbound - see
218
- // `SettingsValues.contextWindow` and the unbound-group filter below.
219
- { key: 'contextWindow', label: 'Context window', kind: 'text' },
220
- // The fast tier sits AFTER `Max tokens` and BEFORE `API key`, because the key
221
- // row is the one a user scrolls to deliberately and putting five rows past it
222
- // would bury it (fast-model-tier §4.5). The rationale survives a fifth row;
223
- // the count in it did not.
224
- //
225
- // `Fast review budget` is a `'text'` row, NOT a new numeric kind (D-H12):
226
- // `SettingsRow.kind` is `'enum' | 'text' | 'secret'`, and `Max tokens` and
227
- // `Fast review` are both bounded numbers already living as text plus an
228
- // adapter parse. A fourth kind for one row would be a new interaction pattern
229
- // in a screen whose whole design is that it edits text.
230
- //
231
- // ITS LABEL IS SHORT BECAUSE THE LABEL COLUMN IS A BUDGET, NOT A HINT SLOT.
232
- // Labels render `.padEnd(18)` below, so one that reaches 18 does not truncate
233
- // and does not wrap - it pushes ITS OWN value right (or butts against it at
234
- // exactly 18) while every other row's value stays put, and the column stops
235
- // being a column. So no `(1-500)` here: no other bounded row carries its range
236
- // either (`Max tokens`, `Fast review`), `clampFastConfig` is the enforcement,
237
- // and `/fast budget` states the range in the one place a user meets it - when
238
- // it refuses a bad one. The name matches that command for the same reason.
239
- { key: 'fastEnabled', label: 'Fast tier', kind: 'enum', options: FAST_ENABLED_OPTIONS },
240
- { key: 'fastModel', label: 'Fast model', kind: 'text' },
241
- { key: 'fastProvider', label: 'Fast provider', kind: 'enum', options: FAST_PROVIDER_OPTIONS },
242
- { key: 'fastReview', label: 'Fast review', kind: 'text' },
243
- { key: 'fastReviewBudget', label: 'Fast budget', kind: 'text' },
244
- // Context compaction sits after the fast rows and still BEFORE `API key`, for
245
- // the reason recorded above that row: the key is the one a user scrolls to
246
- // deliberately, and burying it further would be worse than the ordering is
247
- // better. Three rows, and every label is inside the 18-column budget
248
- // `.padEnd(18)` enforces below.
249
- //
250
- // `Compact at` is a PERCENTAGE and carries no `(50-95)` hint, for the reason
251
- // `Fast budget` records: no other bounded row carries its range either,
252
- // `clampCompactionConfig` is the enforcement, and `/compact threshold` states
253
- // the range in the one place a user meets it — when it refuses a bad one.
254
- { key: 'compactionEnabled', label: 'Auto-compaction', kind: 'enum', options: COMPACTION_ENABLED_OPTIONS },
255
- { key: 'compactionThreshold', label: 'Compact at %', kind: 'text' },
256
- { key: 'compactionKeepTurns', label: 'Keep turns', kind: 'text' },
257
- // Both labels are inside the 18-column budget `.padEnd(18)` enforces below.
258
- { key: 'compactionSubagents', label: 'Compact children', kind: 'enum', options: COMPACTION_ENABLED_OPTIONS },
259
- { key: 'compactionArchive', label: 'Archive dropped', kind: 'enum', options: COMPACTION_ENABLED_OPTIONS },
260
- { key: 'apiKey', label: 'API key', kind: 'secret' },
261
- { key: 'logLevel', label: 'Log level', kind: 'enum', options: LOG_LEVEL_NAMES },
262
- ];
263
- /**
264
- * The cap this setting will ACTUALLY produce against the selected model.
265
- *
266
- * Exported for the tests, and computed on every render rather than in an effect:
267
- * `resolveOutputTokens` is pure, allocation-light and does no I/O — the ceiling
268
- * lookup is a `Map.get` plus at most seven regex tests.
269
- *
270
- * Without this row the settings screen can only show what the user typed, and
271
- * "I set 64000 but answers still stop early" has no answer anywhere in the UI.
272
- */
273
- export function effectiveCapLine(values) {
274
- const parsed = parseMaxTokensInput(values.maxTokens);
275
- if (parsed.kind === 'invalid')
276
- return 'Effective: - (not a number; use a value or "auto")';
277
- const requested = parsed.kind === 'value' ? parsed.value : undefined;
278
- const resolution = resolveOutputTokens({
279
- providerId: values.provider,
280
- modelId: values.model,
281
- ...(requested !== undefined ? { requested } : {}),
282
- });
283
- if (resolution.clampedBy === 'ceiling') {
284
- const ambition = requested ?? DEFAULT_MAX_OUTPUT_TOKENS;
285
- return `Effective: ${resolution.value} (clamped from ${ambition} by the ${values.model} ceiling)`;
286
- }
287
- if (requested === undefined)
288
- return `Effective: ${resolution.value} (auto)`;
289
- return `Effective: ${resolution.value}`;
290
- }
291
- export function SettingsScreen(props) {
292
- return props.draft ? _jsx(ProfileSettingsScreen, { ...props, draft: props.draft })
293
- : _jsx(LegacySettingsScreen, { ...props });
294
- }
295
- function LegacySettingsScreen({ isActive = true, initial, apiKeys, maxRows, cols, scrollOffset, onScrollClamp, theme, caps, onSave, retrySummary, }) {
296
- const [values, setValues] = useState(initial);
297
- const [index, setIndex] = useState(0);
298
- const glyphs = pickGlyphs(caps);
299
- const field = FIELDS[index];
300
- const focusedOffset = useProfileScroll({ maxRows, cols, scrollOffset, onScrollClamp, theme, caps }, index);
301
- const cycle = (dir) => {
302
- if (field.kind !== 'enum' || !field.options)
303
- return;
304
- const opts = field.options;
305
- const cur = opts.indexOf(String(values[field.key]));
306
- const next = (cur + dir + opts.length) % opts.length;
307
- const nextVal = opts[next];
308
- setValues((prev) => {
309
- const updated = { ...prev, [field.key]: nextVal };
310
- // Clear the key editor on provider switch. Never round-trip a resolved
311
- // (possibly env-only) key into the editor — saving would then persist a
312
- // secret the user never typed into the 0600 config file.
313
- if (field.key === 'provider') {
314
- updated.apiKey = '';
315
- }
316
- return updated;
317
- });
318
- };
319
- useInput((input, key) => {
320
- if (!isActive)
321
- return;
322
- if (key.escape)
323
- return; // App closes the overlay.
324
- if (key.upArrow) {
325
- setIndex((i) => (i - 1 + FIELDS.length) % FIELDS.length);
326
- return;
327
- }
328
- // `&& !key.shift` is a real key collision, not a style choice: Shift+Tab is
329
- // the global mode toggle, and without the guard it would also advance the
330
- // field cursor here — the user changes mode and their selection jumps
331
- // (AC-P4). The mode toggle itself is a no-op while an overlay is open, so
332
- // this branch simply has to stay out of the way.
333
- if (key.downArrow || (key.tab && !key.shift)) {
334
- setIndex((i) => (i + 1) % FIELDS.length);
335
- return;
336
- }
337
- if (key.return) {
338
- onSave?.(values);
339
- return;
340
- }
341
- if (field.kind === 'enum') {
342
- if (key.leftArrow)
343
- cycle(-1);
344
- if (key.rightArrow)
345
- cycle(1);
346
- return;
347
- }
348
- // text / secret editing
349
- if (key.backspace || key.delete) {
350
- setValues((prev) => ({ ...prev, [field.key]: String(prev[field.key]).slice(0, -1) }));
351
- return;
352
- }
353
- if (input && !key.ctrl && !key.meta) {
354
- // `stripPasteFrames`, NOT `input` (I-12 / P0-2). `useInput` is a BROADCAST,
355
- // so this handler sees the NUL-framed paste the composer was sent. An API
356
- // key is ~100 characters with no line break, which trips the filter's Tier
357
- // 2 burst rule and gets framed -- and nothing downstream would remove the
358
- // NULs: `trim()` does not treat U+0000 as whitespace, `maskDot` hides the
359
- // damage, and the value is handed to `registerSecret()` and
360
- // `controller.setApiKey()`. The user is told the settings were saved and
361
- // every request afterwards fails to authenticate with nothing on screen to
362
- // explain it. Pasting IS how a key enters this process.
363
- // `stripEnterFrames` INSIDE (tui-shift-enter-copy-queue 3.5): the same
364
- // broadcast carries the newline frame a Shift+Enter produced, and this
365
- // composition order is the one that leaves no NUL in the field -- the
366
- // outer paste strip removes the frame's newline for a single-line field
367
- // exactly as it removes a bare Ctrl+J today, while the reverse order
368
- // would leak the frame's letter as visible text.
369
- const text = stripPasteFrames(stripEnterFrames(input));
370
- if (text.length === 0)
371
- return;
372
- setValues((prev) => ({ ...prev, [field.key]: String(prev[field.key]) + text }));
373
- }
374
- });
375
- const displayValue = (f, selected) => {
376
- const raw = String(values[f.key] ?? '');
377
- if (f.kind === 'secret') {
378
- // Indicate an already-configured key (env or file) without revealing it or
379
- // its length — the editor stays empty until the user types a replacement.
380
- const configured = (apiKeys[values.provider] ?? '').length > 0;
381
- if (raw.length > 0) {
382
- return selected
383
- ? glyphs.maskDot.repeat(Math.min(raw.length, 24))
384
- : maskSecret(raw, { maskChar: glyphs.maskDot, ellipsis: glyphs.ellipsis });
385
- }
386
- if (configured)
387
- return selected ? '(configured - type to replace)' : '(configured)';
388
- return selected ? '(type to set)' : '(none)';
389
- }
390
- if (f.kind === 'enum')
391
- return raw;
392
- // An empty cap field is AUTO, not "unset". `(none)` would read as a missing
393
- // setting, which is the one thing this field can never be.
394
- if (f.key === 'maxTokens' && raw.length === 0)
395
- return 'auto';
396
- // An empty window field is AUTO, not "unset" - the same reading, and the
397
- // second of the TWO render points that must agree (P2-1: the profile
398
- // screen's row fallback below is the other).
399
- if (f.key === 'contextWindow' && raw.length === 0)
400
- return 'auto';
401
- // `(not set)` and NOT `(same as main)`, which is the honest reading of §3.2
402
- // rule 3: an empty `fast.model` does not inherit, it means the tier is
403
- // unconfigured. `(same as main)` is a fact the derived line below states
404
- // when the value literally equals the main model — never a placeholder.
405
- if (f.key === 'fastModel' && raw.length === 0) {
406
- return selected ? '(type a model id)' : '(not set)';
407
- }
408
- if (f.key === 'fastReview' && raw.length === 0)
409
- return 'every 5 turns';
410
- return raw.length > 0 ? raw : selected ? '(type to set)' : '(none)';
411
- };
412
- // One element per row, each `wrap="truncate"` — the contract for OverlayFrame's
413
- // controlled mode. The old title alone was 68 characters and wrapped below 70
414
- // columns, adding a row the frame could not account for (P2-9 / R-8).
415
- const rows = FIELDS.map((f, i) => {
416
- const selected = i === index;
417
- return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: selected ? theme.accent : theme.muted, children: selected ? `${glyphs.caret} ` : ' ' }), _jsx(Text, { color: selected ? theme.assistant : theme.muted, children: (f.key === 'apiKey' ? `API key (${values.provider})` : f.label).padEnd(18) }), _jsx(Text, { color: selected ? theme.primary : theme.muted, children: displayValue(f, selected) }), f.kind === 'enum' && selected && (_jsxs(Text, { color: theme.muted, children: [' (', glyphs.arrowLeft, "/", glyphs.arrowRight, ')'] }))] }, f.key));
418
- });
419
- // One element, `wrap="truncate"`, pushed like every other row — OverlayFrame's
420
- // controlled mode slices by ELEMENT, so a row that wraps desynchronises the
421
- // position indicator.
422
- rows.push(_jsx(Text, { wrap: "truncate", color: theme.muted, children: effectiveCapLine(values) }, "__effective"));
423
- rows.push(_jsx(Text, { wrap: "truncate", color: theme.muted, children: fastTierLine(values, (id) => (apiKeys[id] ?? '').length > 0) }, "__fast"));
424
- /**
425
- * ONE ROW, NOT NINE (llm-api-retry-backoff §6.9).
426
- *
427
- * READ-ONLY, and deliberately so: the nine `retry.*` keys belong to `config set`
428
- * and `config.json`, and a settings screen that exposed a jitter checkbox is a
429
- * settings screen nobody reads. What a user needs HERE is the answer to "is it
430
- * on, and how many" — the discoverable control is `/retry`, which this row names.
431
- */
432
- if (retrySummary) {
433
- rows.push(_jsxs(Text, { wrap: "truncate", color: theme.muted, children: [' ', 'API retries'.padEnd(18), retrySummary] }, "__retry"));
434
- }
435
- rows.push(_jsx(Text, { wrap: "truncate", color: theme.muted, children: "Enter saves. Keys persist to the config file (0600)." }, "__save"));
436
- return (_jsx(OverlayFrame, { title: "Settings", hint: `${glyphs.arrowUp}${glyphs.arrowDown} field ${glyphs.midDot} ${glyphs.arrowLeft}${glyphs.arrowRight} change ${glyphs.midDot} Enter save ${glyphs.midDot} Esc close`, maxRows: maxRows, cols: cols, rows: rows, scrollOffset: focusedOffset, onScrollClamp: onScrollClamp, theme: theme, caps: caps }));
437
- }
438
- // `contextWindow` joins the exclusion list so a bound Main can never leak a
439
- // SECOND copy of the row through PROFILE_FIELDS - the root row belongs to the
440
- // unbound group below, exclusively (AC-11).
441
- const PROFILE_FIELDS = FIELDS.filter((field) => ![
442
- 'provider', 'model', 'baseUrl', 'apiKey', 'fastProvider', 'fastModel', 'fastEnabled',
443
- 'contextWindow',
444
- ].includes(field.key));
445
- function profileSettingsValues(initial, draft) {
446
- const file = draft.baseline;
447
- return { ...initial, provider: file.provider ?? initial.provider,
448
- model: file.model ?? initial.model,
449
- baseUrl: file.baseUrl ?? '', apiKey: '', fastModel: file.fast?.model ?? '',
450
- fastProvider: file.fast?.provider || FAST_INHERIT_PROVIDER,
451
- // SEEDED FROM THE FILE VALUE, like its provider/model/baseUrl siblings
452
- // (AC-11 / P2-3): when env holds an override the file value is not the
453
- // effective one, and this screen edits the FILE.
454
- contextWindow: file.contextWindow == null ? 'auto' : String(file.contextWindow) };
455
- }
456
- /** Only fields changed by the user belong in a settings transaction. */
457
- export function readDirtySettings(initial, values) {
458
- const patch = {};
459
- const dirty = (key) => initial[key] !== values[key];
460
- if (dirty('provider'))
461
- patch.provider = values.provider;
462
- if (dirty('model'))
463
- patch.model = values.model.trim();
464
- if (dirty('baseUrl'))
465
- patch.baseUrl = values.baseUrl.trim();
466
- if (dirty('apiKey') && values.apiKey.trim()) {
467
- patch.apiKeys = { [values.provider]: values.apiKey.trim() };
468
- }
469
- if (dirty('thinkingLevel'))
470
- patch.thinkingLevel = values.thinkingLevel;
471
- if (dirty('showThinking'))
472
- patch.showThinking = values.showThinking === 'on';
473
- if (dirty('liveToolOutput'))
474
- patch.liveToolOutput = values.liveToolOutput === 'on';
475
- if (dirty('logLevel'))
476
- patch.log = { level: values.logLevel };
477
- if (dirty('maxTokens')) {
478
- const parsed = parseMaxTokensInput(values.maxTokens);
479
- if (parsed.kind === 'invalid')
480
- throw new Error('Max tokens: use a number or auto.');
481
- patch.maxTokens = parsed.kind === 'auto' ? null : parsed.value;
482
- }
483
- if (dirty('contextWindow')) {
484
- // TYPO CHANGES NOTHING: the message's `Context window:` prefix is what
485
- // `saveProfileSettings`'s focus logic matches to jump to this row. The
486
- // silent clamp on a value mirrors `config set contextWindow`.
487
- const parsed = parseContextWindowInput(values.contextWindow);
488
- if (parsed.kind === 'invalid')
489
- throw new Error('Context window: use a number or auto.');
490
- patch.contextWindow = parsed.kind === 'auto' ? null : parsed.value;
491
- }
492
- const fast = {};
493
- const parsedFast = readFastSettings(values);
494
- if (dirty('fastModel'))
495
- fast.model = parsedFast.model;
496
- if (dirty('fastProvider'))
497
- fast.provider = parsedFast.provider;
498
- if (dirty('fastEnabled'))
499
- fast.enabled = parsedFast.enabled;
500
- if (dirty('fastReview')) {
501
- if (parsedFast.review === undefined)
502
- throw new Error('Fast review: use a turn count or off.');
503
- fast.review = parsedFast.review;
504
- if (parsedFast.reviewEveryTurns !== undefined) {
505
- fast.reviewEveryTurns = parsedFast.reviewEveryTurns;
506
- }
507
- }
508
- if (dirty('fastReviewBudget')) {
509
- if (parsedFast.reviewMaxPerSession === undefined) {
510
- throw new Error('Fast budget: use a number.');
511
- }
512
- fast.reviewMaxPerSession = parsedFast.reviewMaxPerSession;
513
- }
514
- if (Object.keys(fast).length)
515
- patch.fast = fast;
516
- const compaction = {};
517
- const parsedCompaction = readCompactionSettings(values);
518
- const mapping = { compactionEnabled: 'enabled', compactionThreshold: 'threshold',
519
- compactionKeepTurns: 'keepRecentTurns', compactionSubagents: 'subagents',
520
- compactionArchive: 'archive' };
521
- for (const [field, key] of Object.entries(mapping)) {
522
- if (!dirty(field))
523
- continue;
524
- const value = parsedCompaction[key];
525
- if (value === undefined) {
526
- const label = FIELDS.find((item) => item.key === field).label;
527
- throw new Error(`${label}: use a number.`);
528
- }
529
- Object.assign(compaction, { [key]: value });
530
- }
531
- if (Object.keys(compaction).length)
532
- patch.compaction = compaction;
533
- return patch;
534
- }
535
- function saveError(result) {
536
- if (result.persisted)
537
- return 'Saved; not fully applied. Close and restart. Save disabled.';
538
- const errors = {
539
- busy: 'Busy. Wait for running work to finish, then save again.',
540
- conflict: 'Config changed elsewhere. Reload before saving.',
541
- read_failed: 'Cannot read config. Repair with aragon config edit, then reload.',
542
- write_failed: 'Could not save. Your changes are still here; retry Save.',
543
- invalid: 'Invalid settings. Review the highlighted field and retry.',
544
- };
545
- return errors[result.code ?? ''] ?? 'Could not save. Review settings and retry.';
546
- }
547
- function isKitAction(action) {
548
- return action.type.startsWith('kit-');
549
- }
550
- /**
551
- * ONE REDUCER FOR THE WHOLE SCREEN, TWO OWNERS INSIDE IT (agent-model-kits §4.5).
552
- *
553
- * The kit pages need their own data mutations (create, duplicate, delete, apply)
554
- * but must not introduce a second state object: `Save`, `Esc` and the dirty
555
- * badge are shared, and a second store is how a settings screen starts
556
- * disagreeing with itself. `kitReducer` returns the SAME state shape, so the
557
- * split is invisible from the outside.
558
- */
559
- function settingsReducer(state, action) {
560
- return isKitAction(action) ? kitReducer(state, action) : modelProfileReducer(state, action);
561
- }
562
- function useProfileSettingsState(props) {
563
- const [state, dispatch] = useReducer(settingsReducer, props.draft, createModelProfileState);
564
- const [initial, setInitial] = useState(() => profileSettingsValues(props.initial, props.draft));
565
- const [values, setValues] = useState(initial);
566
- const [index, setIndex] = useState(0);
567
- const [error, setError] = useState();
568
- const [persisted, setPersisted] = useState(false);
569
- const [confirmIndex, setConfirmIndex] = useState(0);
570
- const [reloadPending, setReloadPending] = useState(false);
571
- const offset = useProfileScroll(props, index);
572
- // THE PROBE LIVES HERE, NOT IN THE EDITOR (RV-P0-1): this component survives a
573
- // page switch, the editor does not, and a hook inside the editor would abort its
574
- // own discovery the moment `Discover models` opens the list page.
575
- const probe = useModelProbe(props.probe);
576
- const probeTarget = state.editor
577
- ? editorProbeTarget(state.editor, props.apiKeys) : undefined;
578
- // TWO SLOTS: a verdict and a discovered list answer different questions, and
579
- // opening the list must not erase a verdict the user still wants to read.
580
- const probeViews = visibleProbeViews(probe.test, probe.discovery, probeTarget ?? NO_PROFILE_TARGET, props.probe);
581
- const previousPage = useRef(state.page);
582
- useEffect(() => {
583
- const previous = previousPage.current;
584
- previousPage.current = state.page;
585
- if (state.page !== 'root' || previous === 'discard-confirm')
586
- return;
587
- setIndex(0);
588
- props.onScrollClamp?.(0);
589
- }, [state.page]);
590
- const library = state.draft.profiles ?? emptyModelProfiles();
591
- const glyphs = pickGlyphs(props.caps);
592
- const dirty = state.dirty || Object.keys(values).some((key) => values[key] !== initial[key]);
593
- const fields = [FIELDS.find((item) => item.key === 'fastEnabled'),
594
- ...FIELDS.filter((item) => library.mainId === null
595
- && ['provider', 'model', 'baseUrl', 'contextWindow', 'apiKey'].includes(item.key)),
596
- ...FIELDS.filter((item) => library.fastId === null
597
- && ['fastModel', 'fastProvider'].includes(item.key)), ...PROFILE_FIELDS];
598
- // EIGHT FIXED ROWS now (Main, Fast, Subagent model, Subagent fan-out, Kit pack,
599
- // Manage, Save, Reload) around the `fields` block - derived from ROOT_ROWS so
600
- // the count and the offsets cannot drift apart (see those constants).
601
- const count = fields.length + ROOT_ROWS.length + 2;
602
- const field = fields[index - ROOT_FIRST_FIELD];
603
- const readError = state.draft.readError;
604
- // THREE CONFIRMATIONS SHARE ONE PAGE, which is why the page name - not a
605
- // boolean - is what the renderer and the input hook both branch on.
606
- const confirming = state.page === 'delete-confirm' || state.page === 'discard-confirm'
607
- || state.page === 'kit-delete';
608
- return { state, dispatch, initial, setInitial, values, setValues, index, setIndex,
609
- error, setError, persisted, setPersisted, confirmIndex, setConfirmIndex,
610
- reloadPending, setReloadPending, offset, library, glyphs, dirty, fields, count,
611
- field, readError, confirming, probe, probeTarget, probeViews };
612
- }
613
- function saveProfileSettings(props, view) {
614
- const { persisted, readError, initial, values, fields, state, setError, setIndex, setPersisted } = view;
615
- if (persisted || readError || !props.onProfileSave)
616
- return;
617
- let patch;
618
- try {
619
- patch = readDirtySettings(initial, values);
620
- }
621
- catch (failure) {
622
- const message = failure.message;
623
- setError(message);
624
- const at = fields.findIndex((item) => message.startsWith(`${item.label}:`));
625
- if (at >= 0)
626
- setIndex(at + ROOT_FIRST_FIELD);
627
- return;
628
- }
629
- const result = props.onProfileSave({
630
- ...state.draft, patch: { ...state.draft.patch, ...patch },
631
- });
632
- if (!result.ok) {
633
- setError(saveError(result));
634
- setPersisted(result.persisted);
635
- }
636
- }
637
- function reloadProfileSettings(props, view) {
638
- const { dispatch, setInitial, setValues, setError, setIndex, setReloadPending } = view;
639
- if (!props.onReload)
640
- return;
641
- const next = props.onReload();
642
- dispatch({ type: 'reload', draft: next });
643
- const live = next.liveBaseline;
644
- const refreshed = { ...props.initial, provider: live.provider, model: live.model,
645
- baseUrl: live.baseUrl ?? '', thinkingLevel: live.thinkingLevel,
646
- showThinking: live.showThinking ? 'on' : 'off',
647
- liveToolOutput: live.liveToolOutput ? 'on' : 'off',
648
- maxTokens: live.maxTokens === undefined ? '' : String(live.maxTokens),
649
- contextWindow: live.contextWindow == null ? 'auto' : String(live.contextWindow),
650
- logLevel: live.log?.level ?? props.initial.logLevel,
651
- ...(live.fast ? fastSettingsFrom(live.fast) : {}),
652
- ...(live.compaction ? compactionSettingsFrom(live.compaction) : {}),
653
- };
654
- const nextValues = profileSettingsValues(refreshed, next);
655
- setInitial(nextValues);
656
- setValues(nextValues);
657
- setError(undefined);
658
- setIndex(0);
659
- setReloadPending(false);
660
- }
661
- function cancelProfileSettings(props, view, reloading = false) {
662
- const { persisted, dirty, setReloadPending, setConfirmIndex, dispatch } = view;
663
- if (persisted) {
664
- props.onClose?.();
665
- return;
666
- }
667
- if (!dirty) {
668
- if (reloading)
669
- reloadProfileSettings(props, view);
670
- else
671
- props.onClose?.();
672
- return;
673
- }
674
- setReloadPending(reloading);
675
- setConfirmIndex(0);
676
- dispatch({ type: 'page', page: 'discard-confirm' });
677
- }
678
- function activateRootSetting(props, view) {
679
- const { index, count, readError, persisted, dispatch } = view;
680
- if (index === count - 1) {
681
- cancelProfileSettings(props, view, true);
682
- return;
683
- }
684
- if (readError || persisted)
685
- return;
686
- if (index === ROOT_MAIN || index === ROOT_FAST) {
687
- dispatch({ type: 'page', page: 'picker', role: index === ROOT_MAIN ? 'main' : 'fast' });
688
- }
689
- else if (index === ROOT_SUBAGENT) {
690
- // The user-owned cost switch (D-5): its own picker mode, writing
691
- // `draft.patch.team` rather than a `${role}Id` library key.
692
- dispatch({ type: 'page', page: 'picker', role: 'subagent' });
693
- }
694
- else if (index === ROOT_TEAM) {
695
- // MUST STAY ABOVE THE FALLBACK `else` BELOW, WHICH IS `saveProfileSettings`
696
- // (R-P1-8). A missing or mis-derived constant here does not fail to compile:
697
- // pressing Enter on this row would silently COMMIT the whole draft, so
698
- // `team-fanout-page.test.tsx` asserts that Enter on this row saves nothing.
699
- dispatch({ type: 'page', page: 'team' });
700
- }
701
- else if (index === ROOT_GOVERNANCE) {
702
- // SAME RULE AS THE TEAM BRANCH ABOVE, and the same cost of getting it wrong: this MUST
703
- // stay above the fallback `else`, which is `saveProfileSettings`. A misplaced branch
704
- // compiles and silently commits the whole draft when Enter opens the page.
705
- dispatch({ type: 'page', page: 'governance' });
706
- }
707
- else if (index === ROOT_KIT) {
708
- // The fifth root row opens the manager, not a picker: kits are data the user
709
- // owns here, and `ctrl+K` is where they are CONSUMED (agent-model-kits §4.5).
710
- dispatch({ type: 'page', page: 'kits' });
711
- }
712
- else if (index === ROOT_MANAGE)
713
- dispatch({ type: 'page', page: 'manager' });
714
- else
715
- saveProfileSettings(props, view);
716
- }
717
- function useRootSettingsInput(props, view) {
718
- const { index, count, field, readError, persisted, values, state, setIndex, setValues } = view;
719
- useInput((input, key) => {
720
- if (props.isActive === false)
721
- return;
722
- if (key.escape) {
723
- cancelProfileSettings(props, view);
724
- return;
725
- }
726
- if (key.ctrl && input === 's') {
727
- saveProfileSettings(props, view);
728
- return;
729
- }
730
- if (key.upArrow || (key.tab && key.shift)) {
731
- setIndex((index - 1 + count) % count);
732
- return;
733
- }
734
- if (key.downArrow || key.tab) {
735
- setIndex((index + 1) % count);
736
- return;
737
- }
738
- if (key.return) {
739
- activateRootSetting(props, view);
740
- return;
741
- }
742
- if (!field || readError || persisted || key.ctrl || key.meta)
743
- return;
744
- if (field.kind === 'enum') {
745
- if (!key.leftArrow && !key.rightArrow)
746
- return;
747
- const options = field.options;
748
- const at = options.indexOf(String(values[field.key]));
749
- setValues({ ...values, ...(field.key === 'provider' ? { apiKey: '' } : {}),
750
- [field.key]: options[(at + (key.leftArrow ? -1 : 1) + options.length) % options.length] });
751
- return;
752
- }
753
- const text = stripPasteFrames(stripEnterFrames(input));
754
- const value = key.backspace || key.delete
755
- ? [...String(values[field.key])].slice(0, -1).join('') : String(values[field.key]) + text;
756
- if (field.key === 'apiKey')
757
- registerSecret(value);
758
- if (key.backspace || key.delete || text)
759
- setValues({ ...values, [field.key]: value });
760
- }, { isActive: state.page === 'root' });
761
- }
762
- function useSettingsConfirmationInput(props, view) {
763
- const { state, dispatch, confirmIndex, setConfirmIndex, reloadPending, confirming } = view;
764
- useInput((_input, key) => {
765
- if (props.isActive === false)
766
- return;
767
- if (key.escape) {
768
- dispatch({ type: 'page', page: state.page === 'delete-confirm'
769
- ? 'manager' : 'root' });
770
- return;
771
- }
772
- if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.tab) {
773
- setConfirmIndex((confirmIndex + 1) % 2);
774
- return;
775
- }
776
- if (!key.return)
777
- return;
778
- if (state.page === 'kit-delete') {
779
- dispatch(confirmIndex === 1 ? { type: 'kit-confirm-delete' }
780
- : { type: 'page', page: 'kits' });
781
- return;
782
- }
783
- if (state.page === 'delete-confirm') {
784
- dispatch(confirmIndex === 1 ? { type: 'confirm-delete' }
785
- : { type: 'page', page: 'manager' });
786
- }
787
- else if (confirmIndex === 0)
788
- dispatch({ type: 'page', page: 'root' });
789
- else if (reloadPending)
790
- reloadProfileSettings(props, view);
791
- else
792
- props.onClose?.();
793
- }, { isActive: confirming });
794
- }
795
- /**
796
- * The kit deletion confirmation (agent-model-kits D-9 / AC-30).
797
- *
798
- * `Cancel` IS THE DEFAULT FOCUS, like the profile confirmation next door: the
799
- * `Enter` key that opened this page must not be the one that deletes. The second
800
- * line names what the user loses - a kit, and with it the default pointer and any
801
- * session binding that named it.
802
- */
803
- function renderKitDeleteConfirmation(props, view) {
804
- const { state, confirmIndex, glyphs } = view;
805
- const kit = (state.draft.profiles?.kits ?? []).find((item) => item.id === state.kitDraft?.id);
806
- const rows = ['Cancel', 'Delete'].map((label, at) => (_jsxs(Text, { wrap: "truncate", color: props.theme.primary, children: [confirmIndex === at ? `${glyphs.caret} ` : ' ', label] }, label)));
807
- rows.push(_jsx(Text, { wrap: "truncate", color: props.theme.muted, children: `Deletes kit "${kit?.name ?? ''}". Its three slots stay as they are; only the preset goes.` }, "consequence"));
808
- return _jsx(OverlayFrame, { ...props, title: `Delete kit ${kit?.name ?? ''}?`, hint: "Enter choose | Esc continue", rows: rows, scrollOffset: confirmIndex });
809
- }
810
- function renderSettingsConfirmation(props, view) {
811
- const { state, library, confirmIndex, glyphs } = view;
812
- const deletingKit = state.page === 'kit-delete';
813
- if (deletingKit)
814
- return renderKitDeleteConfirmation(props, view);
815
- const deleting = state.page === 'delete-confirm';
816
- const name = library.entries.find((entry) => entry.id === state.deleteId)?.name ?? '';
817
- // UNBIND-AND-DELETE (D-6): a referenced entry stays deletable in ONE flow,
818
- // and the button names what will happen.
819
- const labels = deleting
820
- ? ['Cancel', state.deleteUsers ? 'Unbind and delete' : 'Delete']
821
- : ['Continue', 'Discard'];
822
- const rows = labels
823
- .map((label, at) => _jsxs(Text, { wrap: "truncate", color: props.theme.primary, children: [confirmIndex === at ? `${glyphs.caret} ` : ' ', label] }, label));
824
- // V-8: A RENDER-ONLY ROW, pushed AFTER the buttons. `confirmIndex` stays a
825
- // 0..1 index over the two buttons and `scrollOffset` follows it, so this
826
- // line must never sit between them or take an array slot of its own.
827
- if (deleting && state.deleteUsers) {
828
- rows.push(_jsxs(Text, { wrap: "truncate", color: props.theme.muted, children: ["Used by ", state.deleteUsers, ". The binding(s) will be cleared."] }, "users"));
829
- }
830
- return _jsx(OverlayFrame, { ...props, title: deleting ? `Delete ${name}?` : 'Discard unsaved changes?', hint: "Enter choose | Esc continue", rows: rows, scrollOffset: confirmIndex });
831
- }
832
- /** Zero-network guard: no key (or no probe port) means no request at all. */
833
- function startTest(view) {
834
- if (view.probeTarget && canProbe(view.probeViews.test)) {
835
- view.probe.startTest(view.probeTarget);
836
- }
837
- }
838
- /** Discover from the draft, then show the list page: the state stays here. */
839
- function startDiscovery(view, dispatch) {
840
- if (!view.probeTarget || !canProbe(view.probeViews.test))
841
- return;
842
- view.probe.startDiscovery(view.probeTarget);
843
- dispatch({ type: 'page', page: 'models' });
844
- }
845
- /**
846
- * Whether the fast tier resolves FOR DISPLAY while the subagent picker is
847
- * open (D-5): the built-in `Fast tier model` row then annotates itself with
848
- * `(fast tier off)`, so choosing it is never a surprise fallback. The same
849
- * enabled + model + config-file-key approximation `fastTierLine` uses - and
850
- * the same env-key blindness (V-10), accepted for consistency with it.
851
- */
852
- function fastTierUnavailable(props, view) {
853
- const { values } = view;
854
- if (values.fastEnabled !== 'on')
855
- return true;
856
- if (values.fastModel.trim().length === 0)
857
- return true;
858
- const provider = values.fastProvider === FAST_INHERIT_PROVIDER
859
- || values.fastProvider.trim().length === 0 ? values.provider : values.fastProvider;
860
- return (props.apiKeys[provider] ?? '').length === 0;
861
- }
862
- function renderProfileSubpage(props, view) {
863
- const { state, library, dispatch, setConfirmIndex } = view;
864
- // THE FAN-OUT PAGE (subagent-fanout 3.4.4). Placed before the picker branch
865
- // because that branch is the unconditional fallback; the page name is unique,
866
- // so its position among the others is arbitrary.
867
- if (state.page === 'team')
868
- return _jsx(TeamFanoutPage, { ...props, view: {
869
- rows: fanoutRows(teamFanoutValues(state.draft), props.teamRegistered),
870
- error: state.error,
871
- }, dispatch: dispatch, onBack: () => dispatch({ type: 'page', page: 'root' }) });
872
- if (state.page === 'governance') {
873
- const config = draftGovernance(state.draft);
874
- return _jsx(GovernanceSettingsPage, { ...props, view: {
875
- rows: governanceSettingRows(config),
876
- error: state.error,
877
- restartNote: governanceRestartNote(config.enabled, props.governanceRegistered),
878
- }, dispatch: dispatch, onBack: () => dispatch({ type: 'page', page: 'root' }) });
879
- }
880
- // THE KIT PAGES (agent-model-kits §4.5). They are dispatched BEFORE the profile
881
- // pages because `'kit-slot'` RENDERS a profile picker while belonging to the
882
- // kit editor - the page name, not the component, decides where the user is.
883
- if (state.page === 'kits')
884
- return _jsx(KitManager, { ...props, rows: kitManagerRows(state), error: state.error, dispatch: dispatch, onBack: () => dispatch({ type: 'page', page: 'root' }) });
885
- if (state.page === 'kit-edit' && state.kitDraft)
886
- return _jsx(KitEditor, { ...props, draft: state.kitDraft, state: state, dispatch: dispatch });
887
- if (state.page === 'kit-slot' && state.kitDraft) {
888
- return renderKitSlotPicker(props, view, state.kitDraft);
889
- }
890
- if (state.page === 'editor' && state.editor)
891
- return _jsx(ModelProfileEditor, { ...props, editor: state.editor, users: profileUsers(library, state.editor.original.id, draftSubagentProfileId(state.draft)), error: state.error, dispatch: dispatch, probeView: view.probeViews.test, probeBusy: view.probe.busy, probeTarget: view.probeTarget, onTest: () => startTest(view), onDiscover: () => startDiscovery(view, dispatch), onCancelProbe: view.probe.cancel });
892
- // A DISCOVERY IS A PAGE, NOT A POPUP: the list is where the answer belongs, and
893
- // the probe state it renders keeps running because it lives one level up.
894
- if (state.page === 'models' && state.editor)
895
- return _jsx(ModelDiscoveryList, { ...props, provider: state.editor.provider, currentModel: state.editor.model, view: view.probeViews.discovery, busy: view.probe.discovery.phase === 'discovering', onChoose: (model) => dispatch({ type: 'choose-model', model }), onRetry: () => startDiscovery(view, dispatch), onBack: () => dispatch({ type: 'page', page: 'editor' }), onCancelProbe: view.probe.cancel });
896
- // A NEW PROFILE SEEDED FROM THE MAIN CONNECTION while the subagent picker is
897
- // open: 'subagent' is picker-only (6.2), so the seed role falls back to
898
- // 'main' while `state.role` keeps driving the select that binds it. 'binding'
899
- // is the kit slot's chooser and seeds the same way.
900
- const createRole = state.role === 'subagent' || state.role === 'binding'
901
- ? 'main' : state.role;
902
- if (state.page === 'picker' || state.page === 'manager')
903
- return _jsx(ModelProfilePicker, { ...props, profiles: library, savedProfiles: state.draft.baseline.modelProfiles, role: state.role, customProfile: createCustomProfile(state.draft, createRole), manager: state.page === 'manager', error: state.error, selectedIdOverride: state.role === 'subagent' ? subagentSelectedId(state.draft) : undefined, subagentProfileId: draftSubagentProfileId(state.draft), fastTierOff: state.role === 'subagent' && fastTierUnavailable(props, view), onSelect: (id) => dispatch({ type: 'select', role: state.role, id }), onCreate: () => dispatch({ type: 'edit', profile: createCustomProfile(state.draft, createRole),
904
- bindNew: state.page === 'picker' }), onEdit: (profile) => dispatch({ type: 'edit', profile }), onDuplicate: (id) => dispatch({ type: 'duplicate', id }), onDelete: (id) => { setConfirmIndex(0); dispatch({ type: 'delete', id }); }, onCancel: () => dispatch({ type: 'page', page: 'root' }) });
905
- return null;
906
- }
907
- /** Which slot value the kit picker should mark `[Selected]`. */
908
- function kitSlotSelection(kitDraft) {
909
- if (kitDraft.slot === 'main')
910
- return kitDraft.mainProfileId || null;
911
- if (kitDraft.slot === 'fast')
912
- return kitDraft.fastProfileId;
913
- if (kitDraft.subagent.model === 'profile')
914
- return kitDraft.subagent.modelProfileId;
915
- return kitDraft.subagent.model === 'fast' ? SUBAGENT_FAST_ROW_ID : null;
916
- }
917
- /**
918
- * The slot chooser: the SAME profile picker, in its `binding` role.
919
- *
920
- * A kit slot can only name a profile, so there is no `Current custom` row and no
921
- * `Same as main` (those are the subagent slot's own three-state vocabulary). The
922
- * subagent slot keeps the `subagent` role, which is why `Fast tier (off - falls
923
- * back to main)` needs no new wording anywhere (RV-P2-6).
924
- */
925
- function renderKitSlotPicker(props, view, kitDraft) {
926
- const { state, library, dispatch } = view;
927
- const role = kitDraft.slot === 'subagent' ? 'subagent' : 'binding';
928
- return _jsx(ModelProfilePicker, { ...props, profiles: library, savedProfiles: state.draft.baseline.modelProfiles, role: role, customProfile: createCustomProfile(state.draft, 'main'), error: state.error, selectedIdOverride: kitSlotSelection(kitDraft), subagentProfileId: draftSubagentProfileId(state.draft), fastTierOff: kitDraft.slot === 'subagent' && fastTierUnavailable(props, view), onSelect: (id) => {
929
- if (kitDraft.slot === 'main') {
930
- dispatch({ type: 'kit-main', id });
931
- return;
932
- }
933
- if (kitDraft.slot === 'fast') {
934
- dispatch({ type: 'kit-fast', id });
935
- return;
936
- }
937
- dispatch({ type: 'kit-subagent',
938
- model: id === null ? 'main' : id === SUBAGENT_FAST_ROW_ID ? 'fast' : 'profile',
939
- modelProfileId: id === null || id === SUBAGENT_FAST_ROW_ID ? null : id });
940
- }, onCreate: () => dispatch({ type: 'edit', profile: createCustomProfile(state.draft, 'main') }), onEdit: (profile) => dispatch({ type: 'edit', profile }), onDuplicate: (id) => dispatch({ type: 'duplicate', id }), onDelete: (id) => dispatch({ type: 'delete', id }), onCancel: () => dispatch({ type: 'kit-cancel' }) });
941
- }
942
- function buildRootSettingsRows(props, view) {
943
- const { library, fields, values, persisted, readError, index, glyphs, state } = view;
944
- const name = (id) => {
945
- const entry = library.entries.find((candidate) => candidate.id === id);
946
- if (!entry)
947
- return 'Current custom';
948
- const missing = !entry.apiKey && !props.apiKeys[entry.provider];
949
- return `${entry.name} ${entry.provider}:${entry.model}${missing ? ' [Missing API key]' : ''}`;
950
- };
951
- // THE SUBAGENT MODEL ROW (D-5), third on the page, summarized from the
952
- // same draft/baseline sources every other derived row here reads. The fast
953
- // tier check mirrors `fastTierLine`'s approximation (enabled + model + a
954
- // config-file key) so the two derived lines can never disagree.
955
- const team = draftTeam(state.draft);
956
- const mainBound = library.entries.find((entry) => entry.id === library.mainId);
957
- const mainConnection = mainBound
958
- ? `${mainBound.provider}:${mainBound.model}`
959
- : `${values.provider}:${values.model}`;
960
- const fastModel = values.fastModel.trim();
961
- const fastProvider = values.fastProvider === FAST_INHERIT_PROVIDER
962
- || values.fastProvider.trim().length === 0 ? values.provider : values.fastProvider;
963
- const fastConnection = values.fastEnabled === 'on' && fastModel.length > 0
964
- && (props.apiKeys[fastProvider] ?? '').length > 0
965
- ? `${fastProvider}:${fastModel}` : null;
966
- const subagentLine = subagentModelSummary({ mode: team.model,
967
- modelProfileId: team.modelProfileId, mainConnection, fastConnection,
968
- profiles: state.draft.profiles,
969
- hasKey: (id) => (props.apiKeys[id] ?? '').length > 0 });
970
- // HELD SLOTS SHOW THE KIT'S EFFECTIVE VALUES (RV-P0-2 / AC-38). Three rows on
971
- // this page read the FILE's bindings while the header reads the live ones, so
972
- // without this the screen says `Main profile Opus` over a header that says
973
- // `haiku` - and the only available conclusion is that the app is broken.
974
- // `Enter` on any of these rows writes an explicit choice, which releases that
975
- // slot (§4.3), so what the user sees is what they are about to change.
976
- const held = heldSlots(state);
977
- const kitTag = held.kitName ? ` (kit ${held.kitName})` : '';
978
- const mainValue = `${name(held.mainId ?? library.mainId)}${held.held.includes('main')
979
- ? kitTag : ''}`;
980
- const fastValue = held.held.includes('fast')
981
- ? `${held.fastId ? name(held.fastId) : 'Off (this kit turns the tier off)'}${kitTag}`
982
- : name(library.fastId);
983
- const subagentValue = held.subagent
984
- ? `${subagentModelSummary({ mode: held.subagent.model,
985
- modelProfileId: held.subagent.modelProfileId, mainConnection, fastConnection,
986
- profiles: state.draft.profiles,
987
- hasKey: (id) => (props.apiKeys[id] ?? '').length > 0 })}${kitTag}`
988
- : subagentLine;
989
- // THE TEAM SUMMARY (subagent-fanout 3.4.4, renamed by
990
- // team-command-forced-dispatch §3.9): a DERIVED row, like the three above it,
991
- // and deliberately not a control - the values are adjusted on the page Enter
992
- // opens, so the root row cannot change one by accident. It now summarises the
993
- // WHOLE section, switch included, because `Team mode` is one of those values
994
- // and a summary that always printed numbers would describe a capability the
995
- // user may have just switched off.
996
- const summary = teamSummary(teamFanoutValues(state.draft));
997
- const lines = [`Main profile ${mainValue}`,
998
- `Fast profile ${fastValue}`,
999
- `Subagent model ${subagentValue}`,
1000
- // `Team`, not `Subagent fan-out`: the row heads a page that now owns
1001
- // four values, only two of which are about fan-out width. `padEnd(18)` is
1002
- // unchanged, so the value column still lines up with `Subagent model`.
1003
- `Team ${summary}`,
1004
- `Governance ${governanceSummary(draftGovernance(state.draft))}`,
1005
- `Kit pack ${kitPackRow(state)}`,
1006
- `Manage profiles ${library.entries.length} saved`,
1007
- ...fields.map((item) => `${item.label.padEnd(18)}${item.key === 'apiKey'
1008
- ? values.apiKey ? 'Configured (replacement)' : props.apiKeys[values.provider]
1009
- ? 'Configured (type to replace)' : '(type to set)'
1010
- : values[item.key] || (item.key === 'maxTokens' || item.key === 'contextWindow'
1011
- ? 'auto' : '(not set)')}`),
1012
- persisted || readError ? 'Save (disabled)' : 'Save settings', 'Reload settings'];
1013
- const rows = lines.map((line, at) => _jsxs(Text, { wrap: "truncate", color: at === index ? props.theme.accent : props.theme.muted, children: [at === index ? `${glyphs.caret} ` : ' ', line] }, at));
1014
- rows.push(_jsx(Text, { wrap: "truncate", color: props.theme.muted, children: effectiveCapLine(values) }, "effective"));
1015
- const overrides = state.draft.liveBaseline.modelProfileState;
1016
- if (overrides?.main.overriddenFields.length || overrides?.fast.overriddenFields.length) {
1017
- rows.push(_jsx(Text, { wrap: "truncate", color: props.theme.muted, children: "Startup overrides active; explicit selection applies now. Restart uses startup overrides." }, "overrides"));
1018
- }
1019
- if (props.retrySummary)
1020
- rows.push(_jsxs(Text, { wrap: "truncate", color: props.theme.muted, children: ["API retries: ", props.retrySummary] }, "retry"));
1021
- return rows;
1022
- }
1023
- function ProfileSettingsScreen(props) {
1024
- const view = useProfileSettingsState(props);
1025
- useRootSettingsInput(props, view);
1026
- useSettingsConfirmationInput(props, view);
1027
- if (view.confirming)
1028
- return renderSettingsConfirmation(props, view);
1029
- const subpage = renderProfileSubpage(props, view);
1030
- if (subpage)
1031
- return subpage;
1032
- const { error, readError, dirty, persisted, index, offset } = view;
1033
- return _jsx(OverlayFrame, { ...props, rows: buildRootSettingsRows(props, view), scrollOffset: offset, title: error ?? (readError ? 'Cannot read config. Repair with aragon config edit; Reload.'
1034
- : dirty ? 'Settings | Unsaved changes' : 'Settings'), hint: persisted ? 'Esc close; restart to apply' : index < ROOT_FIRST_FIELD
1035
- ? 'Enter select/edit | Ctrl+S save | Esc cancel'
1036
- : 'Enter save/action | Ctrl+S save | Esc cancel' });
1037
- }