@selesai/code 0.13.15 → 0.13.18

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 (473) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +2 -14
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.js +3 -9
  5. package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
  6. package/dist/bun/sandbox-env-setup.d.ts +1 -0
  7. package/dist/bun/sandbox-env-setup.js +3 -0
  8. package/dist/cli/auth-command.d.ts +23 -0
  9. package/dist/cli/auth-command.js +102 -0
  10. package/dist/cli/config-selector.js +2 -1
  11. package/dist/cli/setup.d.ts +1 -0
  12. package/dist/cli/setup.js +11 -0
  13. package/dist/cli.js +2 -14
  14. package/dist/config.d.ts +3 -2
  15. package/dist/config.js +9 -4
  16. package/dist/core/agent-session-runtime.js +15 -7
  17. package/dist/core/agent-session.d.ts +2 -6
  18. package/dist/core/agent-session.js +15 -4
  19. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  20. package/dist/core/compaction/branch-summarization.js +2 -1
  21. package/dist/core/extensions/loader.js +3 -0
  22. package/dist/core/extensions/types.d.ts +16 -2
  23. package/dist/core/http-dispatcher.js +2 -0
  24. package/dist/core/keybindings.d.ts +5 -0
  25. package/dist/core/keybindings.js +4 -0
  26. package/dist/core/messages.d.ts +1 -1
  27. package/dist/core/model-config.d.ts +15 -0
  28. package/dist/core/model-config.js +3 -0
  29. package/dist/core/model-runtime.d.ts +1 -0
  30. package/dist/core/model-runtime.js +5 -2
  31. package/dist/core/provider-composer.js +8 -2
  32. package/dist/core/session-export.d.ts +3 -0
  33. package/dist/core/session-export.js +31 -0
  34. package/dist/core/session-manager.d.ts +3 -2
  35. package/dist/core/session-manager.js +40 -13
  36. package/dist/core/skills.d.ts +1 -1
  37. package/dist/core/skills.js +4 -2
  38. package/dist/core/system-prompt.js +10 -10
  39. package/dist/core/tools/bash.js +3 -117
  40. package/dist/core/tools/edit.d.ts +1 -12
  41. package/dist/core/tools/edit.js +5 -163
  42. package/dist/core/tools/find.js +4 -55
  43. package/dist/core/tools/grep.js +4 -60
  44. package/dist/core/tools/ls.js +4 -49
  45. package/dist/core/tools/read.d.ts +4 -0
  46. package/dist/core/tools/read.js +10 -122
  47. package/dist/core/tools/renderers/bash.d.ts +11 -0
  48. package/dist/core/tools/renderers/bash.js +129 -0
  49. package/dist/core/tools/renderers/edit.d.ts +22 -0
  50. package/dist/core/tools/renderers/edit.js +166 -0
  51. package/dist/core/tools/renderers/find.d.ts +9 -0
  52. package/dist/core/tools/renderers/find.js +63 -0
  53. package/dist/core/tools/renderers/grep.d.ts +9 -0
  54. package/dist/core/tools/renderers/grep.js +68 -0
  55. package/dist/core/tools/renderers/index.d.ts +27 -0
  56. package/dist/core/tools/renderers/index.js +46 -0
  57. package/dist/core/tools/renderers/ls.d.ts +9 -0
  58. package/dist/core/tools/renderers/ls.js +57 -0
  59. package/dist/core/tools/renderers/read.d.ts +10 -0
  60. package/dist/core/tools/renderers/read.js +128 -0
  61. package/dist/core/tools/renderers/write.d.ts +9 -0
  62. package/dist/core/tools/renderers/write.js +152 -0
  63. package/dist/core/tools/write.js +5 -146
  64. package/dist/extensions/capability-gateway/index.ts +12 -1
  65. package/dist/extensions/capability-gateway/integration.test.ts +23 -0
  66. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
  67. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  68. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  69. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  70. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  71. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  72. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  73. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  74. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  75. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  76. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  77. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  78. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  79. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  82. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  83. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  84. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  85. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  86. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  87. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  88. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  89. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  91. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  92. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  93. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  99. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  100. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  101. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  102. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  103. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  104. package/dist/extensions/pi-intercom/README.md +16 -2
  105. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  106. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  107. package/dist/extensions/pi-intercom/index.ts +1 -1
  108. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  109. package/dist/extensions/pi-intercom/package.json +1 -1
  110. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  111. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  112. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  113. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  114. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  115. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  116. package/dist/extensions/pi-subagents/README.md +3 -3
  117. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  118. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  119. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  120. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  121. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  122. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  123. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  124. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  125. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  126. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  127. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  128. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  129. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  130. package/dist/extensions/pi-subagents/package.json +6 -4
  131. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  135. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  136. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  137. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  138. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  139. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  140. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  141. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  142. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  143. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  144. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  145. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  146. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  147. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  148. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  149. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  150. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  151. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  152. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  153. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  154. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  155. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  156. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  157. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  158. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  159. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  160. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  161. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  162. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  163. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  164. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  165. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  166. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  167. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  168. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  169. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  170. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  171. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  172. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  176. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  177. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  178. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  179. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  180. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  181. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  182. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  183. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  184. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  185. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  186. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  188. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  189. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  190. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  191. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  192. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  193. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  194. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  201. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  202. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  203. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  204. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  205. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  206. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  207. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  208. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  209. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  210. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  211. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  212. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  213. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  214. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  215. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  216. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  219. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  220. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  221. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  222. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  223. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  224. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  225. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  226. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  228. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  229. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  230. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  231. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  232. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  233. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  234. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  235. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  236. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  237. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  238. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  239. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  240. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  241. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  242. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  243. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  244. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  245. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  250. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  251. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  252. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  256. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  257. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  258. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  259. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  260. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  261. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  262. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  263. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  264. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  265. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  266. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  267. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  268. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  269. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  270. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  271. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  272. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  273. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  275. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  276. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  277. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  278. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  279. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  280. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  281. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  282. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  283. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  284. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  285. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  286. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  287. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  288. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  289. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  290. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  291. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  292. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  294. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  295. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  296. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  297. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  298. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  299. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  300. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  301. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  302. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  303. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  304. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  305. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  306. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  307. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  308. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  309. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  310. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  311. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  312. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  313. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  314. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  315. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  316. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  317. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  318. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  319. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  320. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  321. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  322. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  323. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  324. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  325. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  326. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  327. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  328. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  329. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  330. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  331. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  332. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  333. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  334. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  335. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  336. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  337. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  338. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  339. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  340. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  341. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  342. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  343. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  344. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  345. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  346. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  347. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  348. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  349. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  350. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  351. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  352. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  353. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  354. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  355. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  356. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  357. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  358. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  359. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  360. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  361. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  362. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  363. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  364. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  365. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  366. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  367. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  368. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  369. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  370. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  371. package/dist/extensions/pi-web-agent/src/backends/config.ts +1 -0
  372. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +5 -3
  373. package/dist/extensions/pi-web-agent/src/search/tokenin.ts +7 -3
  374. package/dist/extensions/pi-web-agent/src/types.ts +1 -1
  375. package/dist/extensions/pi-zentui/README.md +17 -0
  376. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  377. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  378. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  379. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  381. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  382. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  383. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  384. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  385. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  386. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  387. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  388. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  389. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  390. package/dist/extensions/pi-zentui/package.json +7 -4
  391. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  392. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  393. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  394. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  395. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  396. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  397. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  398. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  399. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  400. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  401. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  402. package/dist/index.d.ts +1 -1
  403. package/dist/main.js +4 -1
  404. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  405. package/dist/modes/interactive/chat-viewport.js +27 -0
  406. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  407. package/dist/modes/interactive/components/assistant-message.js +30 -13
  408. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  409. package/dist/modes/interactive/components/custom-editor.js +39 -1
  410. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  411. package/dist/modes/interactive/components/index.d.ts +1 -1
  412. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  413. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  414. package/dist/modes/interactive/components/model-selector.js +19 -17
  415. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  416. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  417. package/dist/modes/interactive/components/settings-selector.js +128 -20
  418. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  419. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  420. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  421. package/dist/modes/interactive/components/status-indicator.js +10 -3
  422. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  423. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  424. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  425. package/dist/modes/interactive/components/tool-execution.js +35 -33
  426. package/dist/modes/interactive/components/trust-selector.js +2 -2
  427. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  428. package/dist/modes/interactive/interactive-mode.js +144 -80
  429. package/dist/modes/interactive/session-share.d.ts +15 -0
  430. package/dist/modes/interactive/session-share.js +183 -0
  431. package/dist/modes/interactive/theme/dark.json +2 -1
  432. package/dist/modes/interactive/theme/light.json +2 -1
  433. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  434. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  435. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  436. package/dist/modes/interactive/theme/theme-json.js +129 -0
  437. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  438. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  439. package/dist/modes/interactive/theme/theme.js +18 -119
  440. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  441. package/dist/modes/interactive/tui-renderer.js +65 -0
  442. package/dist/utils/exif-orientation.js +2 -3
  443. package/dist/utils/management-http.d.ts +24 -0
  444. package/dist/utils/management-http.js +53 -0
  445. package/dist/utils/text.d.ts +7 -0
  446. package/dist/utils/text.js +8 -0
  447. package/dist/utils/tools-manager.d.ts +1 -0
  448. package/dist/utils/tools-manager.js +43 -21
  449. package/docs/docs.json +0 -4
  450. package/package.json +4 -4
  451. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  452. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  453. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  454. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  455. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  456. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  457. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  458. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  459. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  460. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  461. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  462. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  463. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  464. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  465. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  466. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  467. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  468. package/dist/skills/implanger/SKILL.md +0 -70
  469. package/dist/skills/output/SKILL.md +0 -49
  470. package/dist/skills/planger/SKILL.md +0 -167
  471. package/dist/skills/workflow/SKILL.md +0 -95
  472. package/docs/workflows.md +0 -18
  473. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Theme JSON validation, kept out of `theme.ts` on purpose.
3
+ *
4
+ * Validating user-authored theme files needs typebox, which costs ~17 MB of module graph to import.
5
+ * Palette lookup does not, so a presentation that only uses built-in themes should never pay for it.
6
+ * `interactive-mode.ts` installs this validator; anything that does not simply skips validation, as
7
+ * built-in themes already do.
8
+ */
9
+ import { type Static, Type } from "typebox";
10
+ declare const ColorValueSchema: Type.TUnion<[Type.TString, Type.TInteger]>;
11
+ declare const ThemeJsonSchema: Type.TObject<{
12
+ $schema: Type.TOptional<Type.TString>;
13
+ name: Type.TString;
14
+ vars: Type.TOptional<Type.TRecord<"^.*$", Type.TUnion<[Type.TString, Type.TInteger]>>>;
15
+ colors: Type.TObject<{
16
+ accent: Type.TUnion<[Type.TString, Type.TInteger]>;
17
+ border: Type.TUnion<[Type.TString, Type.TInteger]>;
18
+ borderAccent: Type.TUnion<[Type.TString, Type.TInteger]>;
19
+ borderMuted: Type.TUnion<[Type.TString, Type.TInteger]>;
20
+ success: Type.TUnion<[Type.TString, Type.TInteger]>;
21
+ error: Type.TUnion<[Type.TString, Type.TInteger]>;
22
+ warning: Type.TUnion<[Type.TString, Type.TInteger]>;
23
+ muted: Type.TUnion<[Type.TString, Type.TInteger]>;
24
+ dim: Type.TUnion<[Type.TString, Type.TInteger]>;
25
+ text: Type.TUnion<[Type.TString, Type.TInteger]>;
26
+ thinkingText: Type.TUnion<[Type.TString, Type.TInteger]>;
27
+ scrollbarTrack: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
28
+ scrollbarThumb: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
29
+ selectedBg: Type.TUnion<[Type.TString, Type.TInteger]>;
30
+ searchMatchBg: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
31
+ searchMatchText: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
32
+ userMessageBg: Type.TUnion<[Type.TString, Type.TInteger]>;
33
+ userMessageText: Type.TUnion<[Type.TString, Type.TInteger]>;
34
+ customMessageBg: Type.TUnion<[Type.TString, Type.TInteger]>;
35
+ customMessageText: Type.TUnion<[Type.TString, Type.TInteger]>;
36
+ customMessageLabel: Type.TUnion<[Type.TString, Type.TInteger]>;
37
+ toolPendingBg: Type.TUnion<[Type.TString, Type.TInteger]>;
38
+ toolSuccessBg: Type.TUnion<[Type.TString, Type.TInteger]>;
39
+ toolErrorBg: Type.TUnion<[Type.TString, Type.TInteger]>;
40
+ toolTitle: Type.TUnion<[Type.TString, Type.TInteger]>;
41
+ toolOutput: Type.TUnion<[Type.TString, Type.TInteger]>;
42
+ mdHeading: Type.TUnion<[Type.TString, Type.TInteger]>;
43
+ mdLink: Type.TUnion<[Type.TString, Type.TInteger]>;
44
+ mdLinkUrl: Type.TUnion<[Type.TString, Type.TInteger]>;
45
+ mdCode: Type.TUnion<[Type.TString, Type.TInteger]>;
46
+ mdCodeBlock: Type.TUnion<[Type.TString, Type.TInteger]>;
47
+ mdCodeBlockBorder: Type.TUnion<[Type.TString, Type.TInteger]>;
48
+ mdQuote: Type.TUnion<[Type.TString, Type.TInteger]>;
49
+ mdQuoteBorder: Type.TUnion<[Type.TString, Type.TInteger]>;
50
+ mdHr: Type.TUnion<[Type.TString, Type.TInteger]>;
51
+ mdListBullet: Type.TUnion<[Type.TString, Type.TInteger]>;
52
+ toolDiffAdded: Type.TUnion<[Type.TString, Type.TInteger]>;
53
+ toolDiffRemoved: Type.TUnion<[Type.TString, Type.TInteger]>;
54
+ toolDiffContext: Type.TUnion<[Type.TString, Type.TInteger]>;
55
+ syntaxComment: Type.TUnion<[Type.TString, Type.TInteger]>;
56
+ syntaxKeyword: Type.TUnion<[Type.TString, Type.TInteger]>;
57
+ syntaxFunction: Type.TUnion<[Type.TString, Type.TInteger]>;
58
+ syntaxVariable: Type.TUnion<[Type.TString, Type.TInteger]>;
59
+ syntaxString: Type.TUnion<[Type.TString, Type.TInteger]>;
60
+ syntaxNumber: Type.TUnion<[Type.TString, Type.TInteger]>;
61
+ syntaxType: Type.TUnion<[Type.TString, Type.TInteger]>;
62
+ syntaxOperator: Type.TUnion<[Type.TString, Type.TInteger]>;
63
+ syntaxPunctuation: Type.TUnion<[Type.TString, Type.TInteger]>;
64
+ thinkingOff: Type.TUnion<[Type.TString, Type.TInteger]>;
65
+ thinkingMinimal: Type.TUnion<[Type.TString, Type.TInteger]>;
66
+ thinkingLow: Type.TUnion<[Type.TString, Type.TInteger]>;
67
+ thinkingMedium: Type.TUnion<[Type.TString, Type.TInteger]>;
68
+ thinkingHigh: Type.TUnion<[Type.TString, Type.TInteger]>;
69
+ thinkingXhigh: Type.TUnion<[Type.TString, Type.TInteger]>;
70
+ thinkingMax: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
71
+ bashMode: Type.TUnion<[Type.TString, Type.TInteger]>;
72
+ }>;
73
+ export: Type.TOptional<Type.TObject<{
74
+ pageBg: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
75
+ cardBg: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
76
+ infoBg: Type.TOptional<Type.TUnion<[Type.TString, Type.TInteger]>>;
77
+ }>>;
78
+ }>;
79
+ export type ThemeColorValue = Static<typeof ColorValueSchema>;
80
+ export type ValidatedThemeJson = Static<typeof ThemeJsonSchema>;
81
+ /** Validate one theme document, throwing a message that names the offending tokens. */
82
+ export declare function validateThemeJson(label: string, json: unknown): ValidatedThemeJson;
83
+ export {};
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Theme JSON validation, kept out of `theme.ts` on purpose.
3
+ *
4
+ * Validating user-authored theme files needs typebox, which costs ~17 MB of module graph to import.
5
+ * Palette lookup does not, so a presentation that only uses built-in themes should never pay for it.
6
+ * `interactive-mode.ts` installs this validator; anything that does not simply skips validation, as
7
+ * built-in themes already do.
8
+ */
9
+ import { Type } from "typebox";
10
+ import { Compile } from "typebox/compile";
11
+ const ColorValueSchema = Type.Union([
12
+ Type.String(), // hex "#ff0000", var ref "primary", or empty ""
13
+ Type.Integer({ minimum: 0, maximum: 255 }), // 256-color index
14
+ ]);
15
+ const ThemeJsonSchema = Type.Object({
16
+ $schema: Type.Optional(Type.String()),
17
+ name: Type.String(),
18
+ vars: Type.Optional(Type.Record(Type.String(), ColorValueSchema)),
19
+ colors: Type.Object({
20
+ // Core UI (11 colors)
21
+ accent: ColorValueSchema,
22
+ border: ColorValueSchema,
23
+ borderAccent: ColorValueSchema,
24
+ borderMuted: ColorValueSchema,
25
+ success: ColorValueSchema,
26
+ error: ColorValueSchema,
27
+ warning: ColorValueSchema,
28
+ muted: ColorValueSchema,
29
+ dim: ColorValueSchema,
30
+ text: ColorValueSchema,
31
+ thinkingText: ColorValueSchema,
32
+ // Scrollbar (2 optional colors)
33
+ scrollbarTrack: Type.Optional(ColorValueSchema),
34
+ scrollbarThumb: Type.Optional(ColorValueSchema),
35
+ // Backgrounds & Content Text (11 required, 2 optional)
36
+ selectedBg: ColorValueSchema,
37
+ searchMatchBg: Type.Optional(ColorValueSchema),
38
+ searchMatchText: Type.Optional(ColorValueSchema),
39
+ userMessageBg: ColorValueSchema,
40
+ userMessageText: ColorValueSchema,
41
+ customMessageBg: ColorValueSchema,
42
+ customMessageText: ColorValueSchema,
43
+ customMessageLabel: ColorValueSchema,
44
+ toolPendingBg: ColorValueSchema,
45
+ toolSuccessBg: ColorValueSchema,
46
+ toolErrorBg: ColorValueSchema,
47
+ toolTitle: ColorValueSchema,
48
+ toolOutput: ColorValueSchema,
49
+ // Markdown (10 colors)
50
+ mdHeading: ColorValueSchema,
51
+ mdLink: ColorValueSchema,
52
+ mdLinkUrl: ColorValueSchema,
53
+ mdCode: ColorValueSchema,
54
+ mdCodeBlock: ColorValueSchema,
55
+ mdCodeBlockBorder: ColorValueSchema,
56
+ mdQuote: ColorValueSchema,
57
+ mdQuoteBorder: ColorValueSchema,
58
+ mdHr: ColorValueSchema,
59
+ mdListBullet: ColorValueSchema,
60
+ // Tool Diffs (3 colors)
61
+ toolDiffAdded: ColorValueSchema,
62
+ toolDiffRemoved: ColorValueSchema,
63
+ toolDiffContext: ColorValueSchema,
64
+ // Syntax Highlighting (9 colors)
65
+ syntaxComment: ColorValueSchema,
66
+ syntaxKeyword: ColorValueSchema,
67
+ syntaxFunction: ColorValueSchema,
68
+ syntaxVariable: ColorValueSchema,
69
+ syntaxString: ColorValueSchema,
70
+ syntaxNumber: ColorValueSchema,
71
+ syntaxType: ColorValueSchema,
72
+ syntaxOperator: ColorValueSchema,
73
+ syntaxPunctuation: ColorValueSchema,
74
+ // Thinking Level Borders (6 colors)
75
+ thinkingOff: ColorValueSchema,
76
+ thinkingMinimal: ColorValueSchema,
77
+ thinkingLow: ColorValueSchema,
78
+ thinkingMedium: ColorValueSchema,
79
+ thinkingHigh: ColorValueSchema,
80
+ thinkingXhigh: ColorValueSchema,
81
+ thinkingMax: Type.Optional(ColorValueSchema),
82
+ // Bash Mode (1 color)
83
+ bashMode: ColorValueSchema,
84
+ }),
85
+ export: Type.Optional(Type.Object({
86
+ pageBg: Type.Optional(ColorValueSchema),
87
+ cardBg: Type.Optional(ColorValueSchema),
88
+ infoBg: Type.Optional(ColorValueSchema),
89
+ })),
90
+ });
91
+ const compiledThemeSchema = Compile(ThemeJsonSchema);
92
+ /** Validate one theme document, throwing a message that names the offending tokens. */
93
+ export function validateThemeJson(label, json) {
94
+ if (!compiledThemeSchema.Check(json)) {
95
+ const errors = Array.from(compiledThemeSchema.Errors(json));
96
+ const missingColors = new Set();
97
+ const otherErrors = [];
98
+ for (const error of errors) {
99
+ if (error.keyword === "required" && error.instancePath === "/colors") {
100
+ const requiredProperties = error.params.requiredProperties;
101
+ for (const requiredProperty of requiredProperties ?? []) {
102
+ missingColors.add(requiredProperty);
103
+ }
104
+ continue;
105
+ }
106
+ const path = error.instancePath || "/";
107
+ otherErrors.push(` - ${path}: ${error.message}`);
108
+ }
109
+ let errorMessage = `Invalid theme "${label}":\n`;
110
+ if (missingColors.size > 0) {
111
+ errorMessage += "\nMissing required color tokens:\n";
112
+ errorMessage += Array.from(missingColors)
113
+ .sort()
114
+ .map((color) => ` - ${color}`)
115
+ .join("\n");
116
+ errorMessage += '\n\nPlease add these colors to your theme\'s "colors" object.';
117
+ errorMessage += "\nSee the built-in themes (dark.json, light.json) for reference values.";
118
+ }
119
+ if (otherErrors.length > 0) {
120
+ errorMessage += `\n\nOther errors:\n${otherErrors.join("\n")}`;
121
+ }
122
+ throw new Error(errorMessage);
123
+ }
124
+ const themeJson = json;
125
+ if (themeJson.name.includes("/")) {
126
+ throw new Error(`Invalid theme name "${themeJson.name}": theme names cannot contain "/" because it is reserved for automatic light/dark theme settings.`);
127
+ }
128
+ return themeJson;
129
+ }
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "colors": {
36
36
  "type": "object",
37
- "description": "Theme color definitions (thinkingMax and scrollbarThumb are optional and use compatible fallbacks)",
37
+ "description": "Theme color definitions (scrollbar, thinkingMax, and search highlight colors are optional and use compatible fallbacks)",
38
38
  "required": [
39
39
  "accent",
40
40
  "border",
@@ -137,6 +137,14 @@
137
137
  "$ref": "#/$defs/colorValue",
138
138
  "description": "Selected item background"
139
139
  },
140
+ "scrollbarTrack": {
141
+ "$ref": "#/$defs/colorValue",
142
+ "description": "Fullscreen scrollbar track foreground (falls back to muted when omitted)"
143
+ },
144
+ "scrollbarThumb": {
145
+ "$ref": "#/$defs/colorValue",
146
+ "description": "Fullscreen scrollbar thumb foreground (falls back to text when omitted)"
147
+ },
140
148
  "searchMatchBg": {
141
149
  "$ref": "#/$defs/colorValue",
142
150
  "description": "Transcript search match background and current-match text (falls back to selectedBg when omitted)"
@@ -1,10 +1,20 @@
1
1
  import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
2
2
  import { type EditorTheme, type MarkdownTheme, type RgbColor, type SelectListTheme, type SettingsListTheme } from "@earendil-works/pi-tui";
3
3
  import type { SourceInfo } from "../../../core/source-info.ts";
4
- export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "thinkingMax" | "searchMatchText" | "bashMode";
5
- export type ThemeBg = "selectedBg" | "scrollbarThumb" | "searchMatchBg" | "userMessageBg" | "customMessageBg" | "toolPendingBg" | "toolSuccessBg" | "toolErrorBg";
6
- type OptionalThemeColor = "thinkingMax" | "searchMatchText";
7
- type OptionalThemeBg = "scrollbarThumb" | "searchMatchBg";
4
+ /** The schema that validates this shape lives in `theme-json.ts`; importing the type is free. */
5
+ import type { ValidatedThemeJson as ThemeJson } from "./theme-json.ts";
6
+ export type { ValidatedThemeJson as ThemeJson } from "./theme-json.ts";
7
+ export type ThemeJsonValidator = (label: string, json: unknown) => ThemeJson;
8
+ /**
9
+ * Install full theme validation. Without it, documents are accepted as-is, which is what built-in
10
+ * themes already do: validating user-authored JSON needs typebox, and a presentation that only uses
11
+ * built-in themes should not pay ~17 MB of module graph for it.
12
+ */
13
+ export declare function setThemeJsonValidator(validator: ThemeJsonValidator): void;
14
+ export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "scrollbarTrack" | "scrollbarThumb" | "searchMatchText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "thinkingMax" | "searchMatchText" | "bashMode";
15
+ export type ThemeBg = "selectedBg" | "searchMatchBg" | "userMessageBg" | "customMessageBg" | "toolPendingBg" | "toolSuccessBg" | "toolErrorBg";
16
+ type OptionalThemeColor = "scrollbarTrack" | "scrollbarThumb" | "thinkingMax" | "searchMatchText";
17
+ type OptionalThemeBg = "searchMatchBg";
8
18
  type ColorMode = "truecolor" | "256color";
9
19
  export declare class Theme {
10
20
  readonly name?: string;
@@ -118,4 +128,3 @@ export declare function getMarkdownTheme(): MarkdownTheme;
118
128
  export declare function getSelectListTheme(): SelectListTheme;
119
129
  export declare function getEditorTheme(): EditorTheme;
120
130
  export declare function getSettingsListTheme(): SettingsListTheme;
121
- export {};
@@ -2,93 +2,18 @@ import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { getCapabilities, } from "@earendil-works/pi-tui";
4
4
  import chalk from "chalk";
5
- import { Type } from "typebox";
6
- import { Compile } from "typebox/compile";
7
5
  import { getCustomThemesDir, getThemesDir } from "../../../config.js";
8
6
  import { closeWatcher, watchWithErrorHandler } from "../../../utils/fs-watch.js";
9
7
  import { highlight, supportsLanguage } from "../../../utils/syntax-highlight.js";
10
- // ============================================================================
11
- // Types & Schema
12
- // ============================================================================
13
- const ColorValueSchema = Type.Union([
14
- Type.String(), // hex "#ff0000", var ref "primary", or empty ""
15
- Type.Integer({ minimum: 0, maximum: 255 }), // 256-color index
16
- ]);
17
- const ThemeJsonSchema = Type.Object({
18
- $schema: Type.Optional(Type.String()),
19
- name: Type.String(),
20
- vars: Type.Optional(Type.Record(Type.String(), ColorValueSchema)),
21
- colors: Type.Object({
22
- // Core UI (10 colors)
23
- accent: ColorValueSchema,
24
- border: ColorValueSchema,
25
- borderAccent: ColorValueSchema,
26
- borderMuted: ColorValueSchema,
27
- success: ColorValueSchema,
28
- error: ColorValueSchema,
29
- warning: ColorValueSchema,
30
- muted: ColorValueSchema,
31
- dim: ColorValueSchema,
32
- text: ColorValueSchema,
33
- thinkingText: ColorValueSchema,
34
- // Backgrounds & Content Text (11 required, 3 optional)
35
- selectedBg: ColorValueSchema,
36
- scrollbarThumb: Type.Optional(ColorValueSchema),
37
- searchMatchBg: Type.Optional(ColorValueSchema),
38
- searchMatchText: Type.Optional(ColorValueSchema),
39
- userMessageBg: ColorValueSchema,
40
- userMessageText: ColorValueSchema,
41
- customMessageBg: ColorValueSchema,
42
- customMessageText: ColorValueSchema,
43
- customMessageLabel: ColorValueSchema,
44
- toolPendingBg: ColorValueSchema,
45
- toolSuccessBg: ColorValueSchema,
46
- toolErrorBg: ColorValueSchema,
47
- toolTitle: ColorValueSchema,
48
- toolOutput: ColorValueSchema,
49
- // Markdown (10 colors)
50
- mdHeading: ColorValueSchema,
51
- mdLink: ColorValueSchema,
52
- mdLinkUrl: ColorValueSchema,
53
- mdCode: ColorValueSchema,
54
- mdCodeBlock: ColorValueSchema,
55
- mdCodeBlockBorder: ColorValueSchema,
56
- mdQuote: ColorValueSchema,
57
- mdQuoteBorder: ColorValueSchema,
58
- mdHr: ColorValueSchema,
59
- mdListBullet: ColorValueSchema,
60
- // Tool Diffs (3 colors)
61
- toolDiffAdded: ColorValueSchema,
62
- toolDiffRemoved: ColorValueSchema,
63
- toolDiffContext: ColorValueSchema,
64
- // Syntax Highlighting (9 colors)
65
- syntaxComment: ColorValueSchema,
66
- syntaxKeyword: ColorValueSchema,
67
- syntaxFunction: ColorValueSchema,
68
- syntaxVariable: ColorValueSchema,
69
- syntaxString: ColorValueSchema,
70
- syntaxNumber: ColorValueSchema,
71
- syntaxType: ColorValueSchema,
72
- syntaxOperator: ColorValueSchema,
73
- syntaxPunctuation: ColorValueSchema,
74
- // Thinking Level Borders (6 colors)
75
- thinkingOff: ColorValueSchema,
76
- thinkingMinimal: ColorValueSchema,
77
- thinkingLow: ColorValueSchema,
78
- thinkingMedium: ColorValueSchema,
79
- thinkingHigh: ColorValueSchema,
80
- thinkingXhigh: ColorValueSchema,
81
- thinkingMax: Type.Optional(ColorValueSchema),
82
- // Bash Mode (1 color)
83
- bashMode: ColorValueSchema,
84
- }),
85
- export: Type.Optional(Type.Object({
86
- pageBg: Type.Optional(ColorValueSchema),
87
- cardBg: Type.Optional(ColorValueSchema),
88
- infoBg: Type.Optional(ColorValueSchema),
89
- })),
90
- });
91
- const validateThemeJson = Compile(ThemeJsonSchema);
8
+ let themeJsonValidator;
9
+ /**
10
+ * Install full theme validation. Without it, documents are accepted as-is, which is what built-in
11
+ * themes already do: validating user-authored JSON needs typebox, and a presentation that only uses
12
+ * built-in themes should not pay ~17 MB of module graph for it.
13
+ */
14
+ export function setThemeJsonValidator(validator) {
15
+ themeJsonValidator = validator;
16
+ }
92
17
  // ============================================================================
93
18
  // Color Utilities
94
19
  // ============================================================================
@@ -229,8 +154,9 @@ function resolveThemeColors(colors, vars = {}) {
229
154
  function withThemeColorFallbacks(colors) {
230
155
  return {
231
156
  ...colors,
157
+ scrollbarTrack: colors.scrollbarTrack ?? colors.muted,
158
+ scrollbarThumb: colors.scrollbarThumb ?? colors.text,
232
159
  thinkingMax: colors.thinkingMax ?? colors.thinkingXhigh,
233
- scrollbarThumb: colors.scrollbarThumb ?? colors.selectedBg,
234
160
  searchMatchBg: colors.searchMatchBg ?? colors.selectedBg,
235
161
  searchMatchText: colors.searchMatchText ?? colors.text,
236
162
  };
@@ -253,6 +179,8 @@ export class Theme {
253
179
  this.fgColors = new Map();
254
180
  const colors = {
255
181
  ...fgColors,
182
+ scrollbarTrack: fgColors.scrollbarTrack ?? fgColors.muted,
183
+ scrollbarThumb: fgColors.scrollbarThumb ?? fgColors.text,
256
184
  thinkingMax: fgColors.thinkingMax ?? fgColors.thinkingXhigh,
257
185
  searchMatchText: fgColors.searchMatchText ?? fgColors.text,
258
186
  };
@@ -262,7 +190,6 @@ export class Theme {
262
190
  this.bgColors = new Map();
263
191
  const backgrounds = {
264
192
  ...bgColors,
265
- scrollbarThumb: bgColors.scrollbarThumb ?? bgColors.selectedBg,
266
193
  searchMatchBg: bgColors.searchMatchBg ?? bgColors.selectedBg,
267
194
  };
268
195
  for (const [key, value] of Object.entries(backgrounds)) {
@@ -409,39 +336,12 @@ function assertThemeNameIsValid(name) {
409
336
  }
410
337
  }
411
338
  function parseThemeJson(label, json) {
412
- if (!validateThemeJson.Check(json)) {
413
- const errors = Array.from(validateThemeJson.Errors(json));
414
- const missingColors = new Set();
415
- const otherErrors = [];
416
- for (const error of errors) {
417
- if (error.keyword === "required" && error.instancePath === "/colors") {
418
- const requiredProperties = error.params.requiredProperties;
419
- for (const requiredProperty of requiredProperties ?? []) {
420
- missingColors.add(requiredProperty);
421
- }
422
- continue;
423
- }
424
- const path = error.instancePath || "/";
425
- otherErrors.push(` - ${path}: ${error.message}`);
426
- }
427
- let errorMessage = `Invalid theme "${label}":\n`;
428
- if (missingColors.size > 0) {
429
- errorMessage += "\nMissing required color tokens:\n";
430
- errorMessage += Array.from(missingColors)
431
- .sort()
432
- .map((color) => ` - ${color}`)
433
- .join("\n");
434
- errorMessage += '\n\nPlease add these colors to your theme\'s "colors" object.';
435
- errorMessage += "\nSee the built-in themes (dark.json, light.json) for reference values.";
436
- }
437
- if (otherErrors.length > 0) {
438
- errorMessage += `\n\nOther errors:\n${otherErrors.join("\n")}`;
439
- }
440
- throw new Error(errorMessage);
339
+ if (themeJsonValidator)
340
+ return themeJsonValidator(label, json);
341
+ if (typeof json !== "object" || json === null || !("colors" in json)) {
342
+ throw new Error(`Invalid theme "${label}": expected an object with a "colors" map.`);
441
343
  }
442
- const themeJson = json;
443
- assertThemeNameIsValid(themeJson.name);
444
- return themeJson;
344
+ return json;
445
345
  }
446
346
  function parseThemeJsonContent(label, content) {
447
347
  let json;
@@ -481,7 +381,6 @@ function createTheme(themeJson, mode, sourcePath) {
481
381
  const bgColors = {};
482
382
  const bgColorKeys = new Set([
483
383
  "selectedBg",
484
- "scrollbarThumb",
485
384
  "searchMatchBg",
486
385
  "userMessageBg",
487
386
  "customMessageBg",
@@ -0,0 +1,20 @@
1
+ import type { Terminal } from "@earendil-works/pi-tui";
2
+ import { type TUI, TuiAltScreen, TuiMainScreen } from "@earendil-works/pi-tui";
3
+ export interface InteractiveTuiOptions {
4
+ readonly tuiMode: "regular" | "fullscreen";
5
+ readonly showHardwareCursor: boolean;
6
+ readonly logDirectory: string;
7
+ readonly terminal?: Terminal;
8
+ readonly onRightClickPaste?: () => void;
9
+ readonly fullscreenCopyOnSelect?: boolean;
10
+ }
11
+ /** Composition root shared by coding-agent presentations. */
12
+ export declare function createInteractiveTui(options: InteractiveTuiOptions & {
13
+ readonly tuiMode: "fullscreen";
14
+ }): TuiAltScreen;
15
+ export declare function createInteractiveTui(options: InteractiveTuiOptions & {
16
+ readonly tuiMode: "regular";
17
+ }): TuiMainScreen;
18
+ export declare function createInteractiveTui(options: InteractiveTuiOptions): TuiMainScreen | TuiAltScreen;
19
+ /** Stable reference for components while InteractiveMode replaces the active renderer. */
20
+ export declare function createInteractiveTuiReference(getTui: () => TUI): TUI;
@@ -0,0 +1,65 @@
1
+ import { ProcessTerminal, TuiAltScreen, TuiMainScreen } from "@earendil-works/pi-tui";
2
+ import { copyToClipboard } from "../../utils/clipboard.js";
3
+ import { openBrowser } from "../../utils/open-browser.js";
4
+ import { keyDisplayText } from "./components/keybinding-hints.js";
5
+ import { theme } from "./theme/theme.js";
6
+ export function createInteractiveTui(options) {
7
+ const terminal = options.terminal ?? new ProcessTerminal();
8
+ if (options.tuiMode === "fullscreen") {
9
+ const styleSearchMatch = (text) => theme.bg("searchMatchBg", theme.fg("searchMatchText", text));
10
+ return new TuiAltScreen(terminal, options.showHardwareCursor, options.logDirectory, {
11
+ searchMatchStyle: (text) => theme.underline(styleSearchMatch(text)),
12
+ searchCurrentMatchStyle: (text) => theme.bold(theme.inverse(styleSearchMatch(text))),
13
+ searchNavigationButtonStyle: (text, hovered) => (hovered ? theme.underline(text) : text),
14
+ scrollToEndIndicator: () => {
15
+ const shortcut = keyDisplayText("tui.altScreen.bottom");
16
+ const label = ` ↓ Jump to latest message${shortcut ? ` · ${shortcut}` : ""} `;
17
+ return theme.bg("selectedBg", theme.fg("text", label));
18
+ },
19
+ openUrl: openBrowser,
20
+ onRightClickPaste: options.onRightClickPaste,
21
+ copyOnSelect: options.fullscreenCopyOnSelect,
22
+ copySelection: async (text) => {
23
+ try {
24
+ await copyToClipboard(text);
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ },
31
+ });
32
+ }
33
+ return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
34
+ }
35
+ /** Stable reference for components while InteractiveMode replaces the active renderer. */
36
+ export function createInteractiveTuiReference(getTui) {
37
+ return new Proxy({}, {
38
+ get: (_target, property) => {
39
+ const tui = getTui();
40
+ const value = Reflect.get(tui, property, tui);
41
+ if (typeof value !== "function")
42
+ return value;
43
+ let methodTui = tui;
44
+ let method = value;
45
+ return (...args) => {
46
+ const currentTui = getTui();
47
+ if (currentTui !== methodTui) {
48
+ const currentMethod = Reflect.get(currentTui, property, currentTui);
49
+ if (typeof currentMethod !== "function") {
50
+ throw new TypeError(`TUI property ${String(property)} is not callable`);
51
+ }
52
+ methodTui = currentTui;
53
+ method = currentMethod;
54
+ }
55
+ return Reflect.apply(method, methodTui, args);
56
+ };
57
+ },
58
+ set: (_target, property, value) => {
59
+ const tui = getTui();
60
+ return Reflect.set(tui, property, value, tui);
61
+ },
62
+ has: (_target, property) => Reflect.has(getTui(), property),
63
+ getPrototypeOf: () => Reflect.getPrototypeOf(getTui()),
64
+ });
65
+ }
@@ -45,9 +45,8 @@ function findJpegTiffOffset(bytes) {
45
45
  const segmentStart = offset + 4;
46
46
  if (segmentStart + 6 > bytes.length)
47
47
  return -1;
48
- if (!hasExifHeader(bytes, segmentStart))
49
- return -1;
50
- return segmentStart + 6;
48
+ if (hasExifHeader(bytes, segmentStart))
49
+ return segmentStart + 6;
51
50
  }
52
51
  if (offset + 4 > bytes.length)
53
52
  return -1;
@@ -0,0 +1,24 @@
1
+ type FetchInput = Parameters<typeof fetch>[0];
2
+ export interface FetchRetryOptions {
3
+ /** Number of additional attempts after the initial request. Defaults to two. */
4
+ maxRetries?: number;
5
+ /** Retry transient HTTP responses as well as transport failures. Defaults to true. */
6
+ retryOnStatus?: boolean;
7
+ /** Overall time budget shared by all attempts. */
8
+ timeoutMs?: number;
9
+ /** Per-attempt timeout. A new timeout is created for every attempt. */
10
+ attemptTimeoutMs?: number;
11
+ }
12
+ /**
13
+ * Fetch a management HTTP resource with a bounded immediate retry.
14
+ *
15
+ * This is intentionally a transport-level helper for idempotent management
16
+ * requests (version checks, catalogs, and downloads). It must not be used for
17
+ * agent/model operations: those can fail after the HTTP request starts and are
18
+ * retried by their semantic caller instead.
19
+ *
20
+ * Caller cancellation and timeoutMs are terminal. attemptTimeoutMs aborts
21
+ * only the current attempt so a hung connection can be retried.
22
+ */
23
+ export declare function fetchWithRetry(input: FetchInput, init?: RequestInit | undefined, options?: FetchRetryOptions): Promise<Response>;
24
+ export {};
@@ -0,0 +1,53 @@
1
+ const RETRYABLE_STATUS_CODES = new Set([408, 425, 429, 500, 502, 503, 504]);
2
+ /**
3
+ * Fetch a management HTTP resource with a bounded immediate retry.
4
+ *
5
+ * This is intentionally a transport-level helper for idempotent management
6
+ * requests (version checks, catalogs, and downloads). It must not be used for
7
+ * agent/model operations: those can fail after the HTTP request starts and are
8
+ * retried by their semantic caller instead.
9
+ *
10
+ * Caller cancellation and timeoutMs are terminal. attemptTimeoutMs aborts
11
+ * only the current attempt so a hung connection can be retried.
12
+ */
13
+ export async function fetchWithRetry(input, init = undefined, options = {}) {
14
+ const maxRetries = options.maxRetries === undefined || !Number.isFinite(options.maxRetries)
15
+ ? 2
16
+ : Math.max(0, Math.floor(options.maxRetries));
17
+ const retryOnStatus = options.retryOnStatus ?? true;
18
+ const parentSignal = init?.signal ?? undefined;
19
+ const timeoutSignal = options.timeoutMs !== undefined && options.timeoutMs > 0 ? AbortSignal.timeout(options.timeoutMs) : undefined;
20
+ const attemptTimeoutMs = options.attemptTimeoutMs !== undefined && options.attemptTimeoutMs > 0 ? options.attemptTimeoutMs : undefined;
21
+ for (let attempt = 0;; attempt++) {
22
+ parentSignal?.throwIfAborted();
23
+ timeoutSignal?.throwIfAborted();
24
+ const attemptTimeoutSignal = attemptTimeoutMs ? AbortSignal.timeout(attemptTimeoutMs) : undefined;
25
+ const signals = [parentSignal, timeoutSignal, attemptTimeoutSignal].filter((signal) => signal !== undefined);
26
+ const signal = signals.length > 1 ? AbortSignal.any(signals) : signals[0];
27
+ try {
28
+ const response = await fetch(input, signal ? { ...init, signal } : init);
29
+ const shouldRetry = retryOnStatus && RETRYABLE_STATUS_CODES.has(response.status) && attempt < maxRetries;
30
+ if (!shouldRetry)
31
+ return response;
32
+ try {
33
+ await response.body?.cancel();
34
+ }
35
+ catch {
36
+ // The response is being discarded before a retry. There is nothing useful to
37
+ // do if cancelling its body also fails.
38
+ }
39
+ }
40
+ catch (error) {
41
+ const attemptTimedOut = attemptTimeoutSignal?.aborted === true && !parentSignal?.aborted && !timeoutSignal?.aborted;
42
+ if (parentSignal?.aborted ||
43
+ timeoutSignal?.aborted ||
44
+ (error instanceof Error &&
45
+ error.name === "AbortError" &&
46
+ !attemptTimedOut &&
47
+ timeoutSignal === undefined) ||
48
+ attempt >= maxRetries) {
49
+ throw error;
50
+ }
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,7 @@
1
+ /** Split a leading UTF-8 byte order mark from decoded text. */
2
+ export declare function splitBom(content: string): {
3
+ bom: string;
4
+ text: string;
5
+ };
6
+ /** Remove a leading UTF-8 byte order mark from decoded text. */
7
+ export declare function stripBom(content: string): string;
@@ -0,0 +1,8 @@
1
+ /** Split a leading UTF-8 byte order mark from decoded text. */
2
+ export function splitBom(content) {
3
+ return content.startsWith("\uFEFF") ? { bom: "\uFEFF", text: content.slice(1) } : { bom: "", text: content };
4
+ }
5
+ /** Remove a leading UTF-8 byte order mark from decoded text. */
6
+ export function stripBom(content) {
7
+ return splitBom(content).text;
8
+ }