@selesai/code 0.13.40 → 0.14.3

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 (1360) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/bun/runtime-setup.js +4 -1
  3. package/dist/cli/args.d.ts +3 -1
  4. package/dist/cli/args.js +76 -33
  5. package/dist/cli/auth-check.d.ts +18 -0
  6. package/dist/cli/auth-check.js +49 -0
  7. package/dist/cli/credential-print.d.ts +5 -15
  8. package/dist/cli/credential-print.js +42 -82
  9. package/dist/cli/file-processor.d.ts +1 -1
  10. package/dist/cli/file-processor.js +2 -1
  11. package/dist/cli/list-models.d.ts +1 -1
  12. package/dist/cli/list-models.js +2 -2
  13. package/dist/cli/startup-ui.js +38 -30
  14. package/dist/config.d.ts +45 -7
  15. package/dist/config.js +134 -18
  16. package/dist/core/agent-session-custom-tools.test.js +64 -0
  17. package/dist/core/agent-session-length-continuation.test.js +7 -3
  18. package/dist/core/agent-session-runtime.js +2 -2
  19. package/dist/core/agent-session-services.d.ts +1 -0
  20. package/dist/core/agent-session-services.js +14 -0
  21. package/dist/core/agent-session.d.ts +180 -40
  22. package/dist/core/agent-session.js +1061 -485
  23. package/dist/core/auth-storage.d.ts +25 -15
  24. package/dist/core/auth-storage.js +242 -66
  25. package/dist/core/bash-executor.js +42 -52
  26. package/dist/core/bug-report.js +1 -1
  27. package/dist/core/cache-warmer.d.ts +1 -0
  28. package/dist/core/cache-warmer.js +15 -1
  29. package/dist/core/compaction/branch-summarization.js +3 -0
  30. package/dist/core/compaction/compaction.d.ts +3 -1
  31. package/dist/core/compaction/compaction.js +156 -79
  32. package/dist/core/compaction/utils.d.ts +2 -1
  33. package/dist/core/compaction/utils.js +25 -18
  34. package/dist/core/crash-log.d.ts +5 -0
  35. package/dist/core/crash-log.js +69 -0
  36. package/dist/core/defaults.d.ts +1 -1
  37. package/dist/core/defaults.js +1 -1
  38. package/dist/core/export-html/template.css +10 -0
  39. package/dist/core/export-html/template.js +72 -18
  40. package/dist/core/export-html/tool-renderer.d.ts +3 -3
  41. package/dist/core/export-html/tool-renderer.js +5 -3
  42. package/dist/core/extensions/index.d.ts +2 -2
  43. package/dist/core/extensions/index.js +1 -1
  44. package/dist/core/extensions/loader.js +138 -55
  45. package/dist/core/extensions/runner.d.ts +38 -5
  46. package/dist/core/extensions/runner.js +220 -7
  47. package/dist/core/extensions/types.d.ts +438 -51
  48. package/dist/core/extensions/types.js +3 -0
  49. package/dist/core/extensions/virtual-modules.js +6 -0
  50. package/dist/core/extensions/wrapper.d.ts +2 -2
  51. package/dist/core/extensions/wrapper.js +3 -3
  52. package/dist/core/footer-data-provider.d.ts +1 -1
  53. package/dist/core/footer-data-provider.js +1 -1
  54. package/dist/core/handoff.d.ts +0 -1
  55. package/dist/core/handoff.js +0 -1
  56. package/dist/core/http-dispatcher.js +5 -0
  57. package/dist/core/index.d.ts +1 -1
  58. package/dist/core/keybindings.d.ts +25 -24
  59. package/dist/core/keybindings.js +27 -6
  60. package/dist/core/mcp-servers.d.ts +134 -0
  61. package/dist/core/mcp-servers.js +223 -0
  62. package/dist/core/model-config.d.ts +122 -5
  63. package/dist/core/model-config.js +35 -1
  64. package/dist/core/model-registry.d.ts +23 -15
  65. package/dist/core/model-registry.js +46 -22
  66. package/dist/core/model-resolver.d.ts +6 -5
  67. package/dist/core/model-resolver.js +51 -21
  68. package/dist/core/model-runtime.d.ts +73 -14
  69. package/dist/core/model-runtime.js +398 -104
  70. package/dist/core/models-store.d.ts +12 -7
  71. package/dist/core/models-store.js +85 -15
  72. package/dist/core/nested-tool-calls.d.ts +102 -0
  73. package/dist/core/nested-tool-calls.js +178 -0
  74. package/dist/core/package-manager.d.ts +8 -1
  75. package/dist/core/package-manager.js +144 -61
  76. package/dist/core/package-manager.test.js +5 -5
  77. package/dist/core/pi-manifest.d.ts +9 -0
  78. package/dist/core/pi-manifest.js +25 -0
  79. package/dist/core/prompt-templates.d.ts +6 -1
  80. package/dist/core/prompt-templates.js +61 -35
  81. package/dist/core/provider-composer.d.ts +44 -19
  82. package/dist/core/provider-composer.js +166 -64
  83. package/dist/core/radius.d.ts +2 -0
  84. package/dist/core/radius.js +2 -0
  85. package/dist/core/remote-catalog-provider.d.ts +8 -1
  86. package/dist/core/remote-catalog-provider.js +25 -13
  87. package/dist/core/resource-loader.d.ts +9 -1
  88. package/dist/core/resource-loader.js +179 -45
  89. package/dist/core/runtime-credentials.d.ts +5 -5
  90. package/dist/core/runtime-credentials.js +11 -8
  91. package/dist/core/sdk.d.ts +16 -7
  92. package/dist/core/sdk.js +57 -24
  93. package/dist/core/session-manager.d.ts +45 -9
  94. package/dist/core/session-manager.js +124 -31
  95. package/dist/core/settings-diagnostics.d.ts +8 -0
  96. package/dist/core/settings-diagnostics.js +20 -0
  97. package/dist/core/settings-manager.d.ts +62 -32
  98. package/dist/core/settings-manager.js +147 -69
  99. package/dist/core/skills.d.ts +5 -2
  100. package/dist/core/skills.js +58 -35
  101. package/dist/core/slash-commands.js +2 -1
  102. package/dist/core/source-info.d.ts +8 -0
  103. package/dist/core/source-info.js +16 -0
  104. package/dist/core/system-prompt.d.ts +9 -3
  105. package/dist/core/system-prompt.js +9 -12
  106. package/dist/core/system-prompt.test.js +2 -7
  107. package/dist/core/tools/bash.d.ts +12 -0
  108. package/dist/core/tools/bash.js +33 -2
  109. package/dist/core/tools/edit-diff.d.ts +0 -5
  110. package/dist/core/tools/edit-diff.js +2 -5
  111. package/dist/core/tools/edit.d.ts +4 -0
  112. package/dist/core/tools/edit.js +31 -11
  113. package/dist/core/tools/find.d.ts +7 -0
  114. package/dist/core/tools/find.js +16 -19
  115. package/dist/core/tools/grep.d.ts +4 -0
  116. package/dist/core/tools/grep.js +5 -1
  117. package/dist/core/tools/index.d.ts +1 -1
  118. package/dist/core/tools/index.js +11 -2
  119. package/dist/core/tools/ls.d.ts +4 -0
  120. package/dist/core/tools/ls.js +5 -1
  121. package/dist/core/tools/output-accumulator.d.ts +11 -0
  122. package/dist/core/tools/output-accumulator.js +40 -10
  123. package/dist/core/tools/read.d.ts +17 -2
  124. package/dist/core/tools/read.js +23 -2
  125. package/dist/core/tools/render-utils.d.ts +6 -0
  126. package/dist/core/tools/render-utils.js +26 -0
  127. package/dist/core/tools/renderers/bash.js +19 -35
  128. package/dist/core/tools/renderers/edit.js +5 -4
  129. package/dist/core/tools/renderers/index.d.ts +2 -2
  130. package/dist/core/tools/renderers/read.js +3 -2
  131. package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
  132. package/dist/core/tools/tool-definition-wrapper.js +3 -1
  133. package/dist/core/tools/truncate.d.ts +14 -0
  134. package/dist/core/tools/truncate.js +29 -0
  135. package/dist/core/tools/write.d.ts +4 -0
  136. package/dist/core/tools/write.js +6 -2
  137. package/dist/core/trust-manager.js +3 -1
  138. package/dist/core/usage-totals.d.ts +2 -0
  139. package/dist/core/usage-totals.js +23 -0
  140. package/dist/core/virtual-models.d.ts +116 -0
  141. package/dist/core/virtual-models.js +123 -0
  142. package/dist/defaults/models.json +32 -0
  143. package/dist/defaults/settings.json +1 -9
  144. package/dist/extensions/codemode/execute.d.ts +15 -0
  145. package/dist/extensions/codemode/execute.js +645 -0
  146. package/dist/extensions/codemode/execute.lazy.d.ts +2 -0
  147. package/dist/extensions/codemode/execute.lazy.js +2 -0
  148. package/dist/extensions/codemode/index.d.ts +20 -0
  149. package/dist/extensions/codemode/index.js +31 -0
  150. package/dist/extensions/codemode/renderer.d.ts +11 -0
  151. package/dist/extensions/codemode/renderer.js +136 -0
  152. package/dist/extensions/codemode/tool.d.ts +129 -0
  153. package/dist/extensions/codemode/tool.js +275 -0
  154. package/dist/extensions/context-compaction-reminder.ts +1 -1
  155. package/dist/extensions/grep-app/index.ts +2 -10
  156. package/dist/extensions/herdr-agent-state.ts +1 -1
  157. package/dist/extensions/{pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts → index.d.ts} +0 -1
  158. package/dist/extensions/index.js +12 -0
  159. package/dist/extensions/jev/classifier-context.ts +54 -0
  160. package/dist/extensions/jev/classifier.test.ts +150 -0
  161. package/dist/extensions/jev/classifier.ts +191 -0
  162. package/dist/extensions/jev/decisions.test.ts +56 -47
  163. package/dist/extensions/jev/decisions.ts +94 -109
  164. package/dist/extensions/jev/test-support.ts +33 -38
  165. package/dist/extensions/jev-advisory-lifecycle.test.ts +12 -12
  166. package/dist/extensions/jev-advisory-memory.test.ts +9 -9
  167. package/dist/extensions/jev-advisory-recommendations.test.ts +8 -8
  168. package/dist/extensions/jev-ask-tool.test.ts +41 -45
  169. package/dist/extensions/jev-ask-tool.ts +11 -39
  170. package/dist/extensions/jev-find-source.test.ts +26 -0
  171. package/dist/extensions/jev-find-source.ts +58 -19
  172. package/dist/extensions/jev-tool-ranker.test.ts +185 -0
  173. package/dist/extensions/jev-tool-ranker.ts +169 -0
  174. package/dist/{core → extensions}/llama/client.d.ts +2 -0
  175. package/dist/{core → extensions}/llama/client.js +7 -3
  176. package/dist/{core → extensions}/llama/index.js +13 -2
  177. package/dist/{core → extensions}/llama/provider.d.ts +1 -1
  178. package/dist/extensions/llama/provider.js +235 -0
  179. package/dist/extensions/mcp/cli.d.ts +20 -0
  180. package/dist/extensions/mcp/cli.js +496 -0
  181. package/dist/extensions/mcp/cli.lazy.d.ts +2 -0
  182. package/dist/extensions/mcp/cli.lazy.js +2 -0
  183. package/dist/extensions/mcp/config.d.ts +83 -0
  184. package/dist/extensions/mcp/config.js +193 -0
  185. package/dist/extensions/mcp/index.d.ts +78 -0
  186. package/dist/extensions/mcp/index.js +1201 -0
  187. package/dist/extensions/mcp/log.d.ts +15 -0
  188. package/dist/extensions/mcp/log.js +65 -0
  189. package/dist/extensions/mcp/oauth.d.ts +97 -0
  190. package/dist/extensions/mcp/oauth.js +401 -0
  191. package/dist/extensions/mcp/resources.d.ts +41 -0
  192. package/dist/extensions/mcp/resources.js +260 -0
  193. package/dist/extensions/mcp/runtime.d.ts +96 -0
  194. package/dist/extensions/mcp/runtime.js +412 -0
  195. package/dist/extensions/mcp/runtime.lazy.d.ts +2 -0
  196. package/dist/extensions/mcp/runtime.lazy.js +2 -0
  197. package/dist/extensions/mcp/tools.d.ts +86 -0
  198. package/dist/extensions/mcp/tools.js +252 -0
  199. package/dist/extensions/mcp/ui.d.ts +59 -0
  200. package/dist/extensions/mcp/ui.js +185 -0
  201. package/dist/extensions/package.json +2 -1
  202. package/dist/extensions/pi-graft/index.ts +4 -19
  203. package/dist/extensions/pi-graft/lifecycle.test.ts +32 -25
  204. package/dist/extensions/pi-graft/tools.ts +6 -0
  205. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +25 -0
  206. package/dist/extensions/pi-hermes-memory/README.md +140 -4
  207. package/dist/extensions/pi-hermes-memory/package-lock.json +624 -2720
  208. package/dist/extensions/pi-hermes-memory/package.json +9 -7
  209. package/dist/extensions/pi-hermes-memory/scripts/benchmark-memory-startup.mjs +72 -0
  210. package/dist/extensions/pi-hermes-memory/scripts/check-production-install.mjs +107 -0
  211. package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +2 -1
  212. package/dist/extensions/pi-hermes-memory/src/config.ts +35 -0
  213. package/dist/extensions/pi-hermes-memory/src/constants.ts +62 -15
  214. package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +374 -50
  215. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +7 -4
  216. package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +19 -14
  217. package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +75 -1
  218. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +322 -22
  219. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +8 -0
  220. package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +193 -54
  221. package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +6 -2
  222. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +33 -5
  223. package/dist/extensions/pi-hermes-memory/src/index.ts +116 -47
  224. package/dist/extensions/pi-hermes-memory/src/memory-initialization.ts +101 -0
  225. package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +10 -2
  226. package/dist/extensions/pi-hermes-memory/src/store/db.ts +34 -9
  227. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +44 -8
  228. package/dist/extensions/pi-hermes-memory/src/store/schema.ts +3 -1
  229. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +141 -0
  230. package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +17 -6
  231. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +20 -10
  232. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +1 -17
  233. package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +2 -10
  234. package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +4 -8
  235. package/dist/extensions/pi-hermes-memory/src/types.ts +48 -0
  236. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +108 -0
  237. package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +1185 -42
  238. package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +57 -1
  239. package/dist/extensions/pi-hermes-memory/tests/handlers/lazy-memory-hooks.test.ts +128 -0
  240. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +844 -1
  241. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +16 -0
  242. package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +512 -3
  243. package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +38 -0
  244. package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +183 -2
  245. package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +1 -3
  246. package/dist/extensions/pi-hermes-memory/tests/index.test.ts +17 -0
  247. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +21 -0
  248. package/dist/extensions/pi-hermes-memory/tests/lazy-startup.test.ts +313 -0
  249. package/dist/extensions/pi-hermes-memory/tests/memory-initialization.test.ts +182 -0
  250. package/dist/extensions/pi-hermes-memory/tests/prompt-injection.test.ts +184 -0
  251. package/dist/extensions/pi-hermes-memory/tests/skill-discovery-contract.test.ts +60 -0
  252. package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-lazy-probe.test.ts +80 -0
  253. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +2 -0
  254. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +79 -0
  255. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +268 -0
  256. package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +29 -0
  257. package/dist/extensions/pi-hermes-memory/tests/store/usage-tracking.test.ts +170 -0
  258. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +80 -1
  259. package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +51 -0
  260. package/dist/extensions/pi-intercom/CHANGELOG.md +66 -0
  261. package/dist/extensions/pi-intercom/README.md +100 -12
  262. package/dist/extensions/pi-intercom/broker/broker.ts +28 -12
  263. package/dist/extensions/pi-intercom/broker/client.ts +3 -0
  264. package/dist/extensions/pi-intercom/broker/cross-machine-provenance.test.ts +63 -0
  265. package/dist/extensions/pi-intercom/broker/protocol.ts +64 -0
  266. package/dist/extensions/pi-intercom/broker/spawn.test.ts +58 -167
  267. package/dist/extensions/pi-intercom/broker/spawn.ts +40 -87
  268. package/dist/extensions/pi-intercom/cli.mjs +6 -0
  269. package/dist/extensions/pi-intercom/cli.test.ts +428 -0
  270. package/dist/extensions/pi-intercom/cli.ts +343 -0
  271. package/dist/extensions/pi-intercom/config.test.ts +61 -1
  272. package/dist/extensions/pi-intercom/config.ts +53 -2
  273. package/dist/extensions/pi-intercom/cross-machine-discovery.test.ts +218 -0
  274. package/dist/extensions/pi-intercom/cross-machine-discovery.ts +140 -0
  275. package/dist/extensions/pi-intercom/cross-machine-envelope.test.ts +106 -0
  276. package/dist/extensions/pi-intercom/cross-machine-envelope.ts +92 -0
  277. package/dist/extensions/pi-intercom/cross-machine-integration.test.ts +25 -0
  278. package/dist/extensions/pi-intercom/cross-machine-transport.test.ts +106 -0
  279. package/dist/extensions/pi-intercom/cross-machine-transport.ts +110 -0
  280. package/dist/extensions/pi-intercom/extension-api.ts +14 -0
  281. package/dist/extensions/pi-intercom/handover.test.ts +88 -0
  282. package/dist/extensions/pi-intercom/handover.ts +115 -0
  283. package/dist/extensions/pi-intercom/herdr-location.test.ts +173 -0
  284. package/dist/extensions/pi-intercom/herdr-location.ts +137 -0
  285. package/dist/extensions/pi-intercom/human-priority.pi.test.ts +489 -0
  286. package/dist/extensions/pi-intercom/index.ts +582 -164
  287. package/dist/extensions/pi-intercom/intercom.integration.test.ts +590 -22
  288. package/dist/extensions/pi-intercom/package.json +12 -2
  289. package/dist/extensions/pi-intercom/project-agent.ts +1 -1
  290. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +26 -2
  291. package/dist/extensions/pi-intercom/test/handover-picker.test.ts +134 -0
  292. package/dist/extensions/pi-intercom/test/inline-message.test.ts +43 -0
  293. package/dist/extensions/pi-intercom/types.d.ts +247 -0
  294. package/dist/extensions/pi-intercom/types.js +2 -0
  295. package/dist/extensions/pi-intercom/types.ts +39 -1
  296. package/dist/extensions/pi-intercom/ui/handover-picker.ts +318 -0
  297. package/dist/extensions/pi-intercom/ui/inline-message.ts +10 -3
  298. package/dist/extensions/pi-intercom/ui/session-list.ts +28 -15
  299. package/dist/extensions/pi-subagents/.github/workflows/release.yml +5 -1
  300. package/dist/extensions/pi-subagents/.github/workflows/test.yml +188 -18
  301. package/dist/extensions/pi-subagents/CHANGELOG.md +514 -1
  302. package/dist/extensions/pi-subagents/README.md +7 -5
  303. package/dist/extensions/pi-subagents/VISION.md +6 -0
  304. package/dist/extensions/pi-subagents/agents/reviewer.md +7 -5
  305. package/dist/extensions/pi-subagents/agents/worker.md +1 -1
  306. package/dist/extensions/pi-subagents/docs/agents.md +75 -35
  307. package/dist/extensions/pi-subagents/docs/configuration.md +156 -25
  308. package/dist/extensions/pi-subagents/docs/extension-api.md +113 -29
  309. package/dist/extensions/pi-subagents/docs/missions.md +46 -14
  310. package/dist/extensions/pi-subagents/docs/models.md +22 -84
  311. package/dist/extensions/pi-subagents/docs/observability.md +49 -24
  312. package/dist/extensions/pi-subagents/docs/standalone-background.md +59 -0
  313. package/dist/extensions/pi-subagents/docs/tool-reference.md +167 -116
  314. package/dist/extensions/pi-subagents/docs/watchdog.md +41 -10
  315. package/dist/extensions/pi-subagents/docs/workflows.md +239 -163
  316. package/dist/extensions/pi-subagents/examples/typed-gate/.pi/agents/classifier.md +14 -0
  317. package/dist/extensions/pi-subagents/examples/typed-gate/README.md +42 -0
  318. package/dist/extensions/pi-subagents/examples/typed-gate/classify +38 -0
  319. package/dist/extensions/pi-subagents/examples/typed-gate/workflow.js +32 -0
  320. package/dist/extensions/pi-subagents/index.ts +11 -3
  321. package/dist/extensions/pi-subagents/inspector-runner.mjs +3 -3
  322. package/dist/extensions/pi-subagents/package-lock.json +517 -1129
  323. package/dist/extensions/pi-subagents/package.json +22 -11
  324. package/dist/extensions/pi-subagents/prompts/council.md +7 -4
  325. package/dist/extensions/pi-subagents/prompts/parallel-review.md +2 -2
  326. package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
  327. package/dist/extensions/pi-subagents/runner-peer-loader.mjs +21 -0
  328. package/dist/extensions/pi-subagents/runner-peer-preload.mjs +30 -0
  329. package/dist/extensions/pi-subagents/scripts/build-package.mjs +79 -0
  330. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +2 -2
  331. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +46 -27
  332. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +11 -7
  333. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +78 -73
  334. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +4 -5
  335. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +10 -2
  336. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +69 -67
  337. package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +3 -3
  338. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +21 -10
  339. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +113 -113
  340. package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +91 -4
  341. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +15 -9
  342. package/dist/extensions/pi-subagents/src/agents/agents.ts +432 -193
  343. package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +6 -1
  344. package/dist/extensions/pi-subagents/src/agents/global-npm-root.ts +58 -0
  345. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +5 -2
  346. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +22 -18
  347. package/dist/extensions/pi-subagents/src/agents/skills.ts +43 -10
  348. package/dist/extensions/pi-subagents/src/api/delegation.ts +20 -1
  349. package/dist/extensions/pi-subagents/src/api/inspectors.ts +27 -0
  350. package/dist/extensions/pi-subagents/src/api/preflight.ts +140 -62
  351. package/dist/extensions/pi-subagents/src/api/required-child-extensions.ts +6 -0
  352. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
  353. package/dist/extensions/pi-subagents/src/extension/config.ts +24 -40
  354. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +4 -1
  355. package/dist/extensions/pi-subagents/src/extension/doctor.ts +18 -15
  356. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +87 -13
  357. package/dist/extensions/pi-subagents/src/extension/herdr-pi-bridge.ts +162 -0
  358. package/dist/extensions/pi-subagents/src/extension/index.ts +280 -268
  359. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +76 -37
  360. package/dist/extensions/pi-subagents/src/extension/reply-workflow-script.ts +67 -0
  361. package/dist/extensions/pi-subagents/src/extension/rpc.ts +34 -11
  362. package/dist/extensions/pi-subagents/src/extension/schemas.ts +116 -205
  363. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +13 -5
  364. package/dist/extensions/pi-subagents/src/extension/tool-activation.ts +146 -0
  365. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +77 -90
  366. package/dist/extensions/pi-subagents/src/extension/upgrade-notice.ts +40 -0
  367. package/dist/extensions/pi-subagents/src/inspectors/actions.ts +148 -0
  368. package/dist/extensions/pi-subagents/src/inspectors/ghostty/actions.ts +74 -0
  369. package/dist/extensions/pi-subagents/src/inspectors/ghostty/plugin.ts +29 -0
  370. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +100 -180
  371. package/dist/extensions/pi-subagents/src/inspectors/herdr/plugin.ts +20 -0
  372. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +2 -2
  373. package/dist/extensions/pi-subagents/src/inspectors/{herdr/inspector-runner.ts → inspector-runner.ts} +13 -13
  374. package/dist/extensions/pi-subagents/src/inspectors/plugins.ts +75 -0
  375. package/dist/extensions/pi-subagents/src/inspectors/{herdr/session-roots-codec.ts → session-roots-codec.ts} +4 -15
  376. package/dist/extensions/pi-subagents/src/inspectors/{herdr/shell-command.ts → shell-command.ts} +1 -1
  377. package/dist/extensions/pi-subagents/src/inspectors/types.ts +51 -0
  378. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +38 -53
  379. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +53 -9
  380. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +69 -55
  381. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +7 -2
  382. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +45 -32
  383. package/dist/extensions/pi-subagents/src/missions/store.ts +11 -2
  384. package/dist/extensions/pi-subagents/src/policy/authority.ts +5 -1
  385. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +30 -18
  386. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +59 -9
  387. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +18 -2
  388. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +463 -248
  389. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +106 -66
  390. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +33 -20
  391. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +47 -17
  392. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -5
  393. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +24 -11
  394. package/dist/extensions/pi-subagents/src/runs/background/await-async-run.ts +78 -0
  395. package/dist/extensions/pi-subagents/src/runs/background/binary-bootstrap.ts +66 -0
  396. package/dist/extensions/pi-subagents/src/runs/background/calendar-schedule.ts +90 -0
  397. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -2
  398. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +19 -38
  399. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +62 -3
  400. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +82 -10
  401. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +259 -21
  402. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +30 -3
  403. package/dist/extensions/pi-subagents/src/runs/background/pid-namespace.ts +18 -0
  404. package/dist/extensions/pi-subagents/src/runs/background/process-terminal-candidate.ts +98 -0
  405. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +18 -97
  406. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +14 -5
  407. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +66 -12
  408. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +4 -3
  409. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +126 -45
  410. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +11 -6
  411. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +18 -7
  412. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +43 -51
  413. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +8 -1
  414. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +5 -4
  415. package/dist/extensions/pi-subagents/src/runs/background/runner-http-dispatcher.ts +119 -0
  416. package/dist/extensions/pi-subagents/src/runs/background/runner-startup-failure.ts +56 -0
  417. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +233 -69
  418. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +67 -16
  419. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +21 -3
  420. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner-bootstrap.ts +276 -0
  421. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +592 -573
  422. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +177 -29
  423. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +77 -28
  424. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +10 -4
  425. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +7 -13
  426. package/dist/extensions/pi-subagents/src/runs/background/workflow-terminal-proof.ts +41 -23
  427. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +19 -8
  428. package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +130 -7
  429. package/dist/extensions/pi-subagents/src/runs/foreground/command-action.ts +41 -0
  430. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +267 -385
  431. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +4 -2
  432. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +6 -10
  433. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1158 -413
  434. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +3 -1
  435. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +2 -1
  436. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +200 -74
  437. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +133 -34
  438. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +6 -1
  439. package/dist/extensions/pi-subagents/src/runs/shared/child-commands.ts +228 -0
  440. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +18 -18
  441. package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +16 -4
  442. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +55 -12
  443. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +6 -3
  444. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +11 -1
  445. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +367 -74
  446. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +50 -86
  447. package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +288 -0
  448. package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
  449. package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
  450. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +5 -5
  451. package/dist/extensions/pi-subagents/src/runs/shared/effective-system-prompt.ts +33 -0
  452. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +49 -10
  453. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +61 -9
  454. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +16 -9
  455. package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +55 -1
  456. package/dist/extensions/pi-subagents/src/runs/shared/git-environment.ts +1 -1
  457. package/dist/extensions/pi-subagents/src/runs/shared/herdr-connection.ts +134 -0
  458. package/dist/extensions/pi-subagents/src/runs/shared/herdr-external-adapters.ts +169 -0
  459. package/dist/extensions/pi-subagents/src/runs/shared/herdr-machine.ts +279 -0
  460. package/dist/extensions/pi-subagents/src/runs/shared/herdr-pi-protocol.ts +59 -0
  461. package/dist/extensions/pi-subagents/src/runs/shared/herdr-placed-run.ts +263 -0
  462. package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +6 -2
  463. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +108 -13
  464. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +23 -7
  465. package/dist/extensions/pi-subagents/src/runs/shared/model-resolution-diagnostic.ts +76 -0
  466. package/dist/extensions/pi-subagents/src/runs/shared/{model-fallback.ts → model-resolution.ts} +65 -245
  467. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +30 -11
  468. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +24 -3
  469. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +5 -4
  470. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +55 -7
  471. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +14 -4
  472. package/dist/extensions/pi-subagents/src/runs/shared/partial-output.ts +48 -0
  473. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +12 -4
  474. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +88 -1
  475. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +12 -3
  476. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +160 -9
  477. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +35 -34
  478. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +58 -19
  479. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +2 -2
  480. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +21 -0
  481. package/dist/extensions/pi-subagents/src/runs/shared/usage-reconciliation.ts +73 -0
  482. package/dist/extensions/pi-subagents/src/runs/shared/workflow-async-child-guidance.ts +18 -0
  483. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-apply.ts +160 -0
  484. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +42 -20
  485. package/dist/extensions/pi-subagents/src/runs/shared/worktree-lock.ts +29 -0
  486. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +27 -4
  487. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +94 -26
  488. package/dist/extensions/pi-subagents/src/shared/child-cache-retention.ts +43 -0
  489. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +5 -3
  490. package/dist/extensions/pi-subagents/src/shared/disabled-features.ts +123 -0
  491. package/dist/extensions/pi-subagents/src/shared/extension-context.ts +14 -1
  492. package/dist/extensions/pi-subagents/src/shared/file-lease.ts +74 -0
  493. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +27 -77
  494. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +70 -10
  495. package/dist/extensions/pi-subagents/src/shared/model-info.ts +10 -1
  496. package/dist/extensions/pi-subagents/src/shared/opencode-session-headers.ts +30 -0
  497. package/dist/extensions/pi-subagents/src/shared/package-version.ts +17 -0
  498. package/dist/extensions/pi-subagents/src/shared/parent-wake.ts +66 -0
  499. package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +71 -58
  500. package/dist/extensions/pi-subagents/src/shared/required-child-extensions.ts +115 -0
  501. package/dist/extensions/pi-subagents/src/shared/settings-file-lease.ts +36 -0
  502. package/dist/extensions/pi-subagents/src/shared/settings.ts +7 -4
  503. package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +1 -5
  504. package/dist/extensions/pi-subagents/src/shared/types.ts +146 -48
  505. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +28 -2
  506. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +15 -1
  507. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +19 -4
  508. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +13 -2
  509. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +15 -15
  510. package/dist/extensions/pi-subagents/src/slash/subagent-cost.ts +46 -9
  511. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +29 -16
  512. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +201 -26
  513. package/dist/extensions/pi-subagents/src/tui/fleet.ts +33 -16
  514. package/dist/extensions/pi-subagents/src/tui/render.ts +334 -103
  515. package/dist/extensions/pi-subagents/src/tui/running-tone.ts +28 -0
  516. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +27 -28
  517. package/dist/extensions/pi-subagents/src/watchdog/diff-tool.ts +47 -12
  518. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +2 -2
  519. package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +22 -2
  520. package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +17 -17
  521. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +24 -8
  522. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +43 -39
  523. package/dist/extensions/pi-subagents/src/watchdog/render.ts +2 -2
  524. package/dist/extensions/pi-subagents/src/watchdog/review.ts +127 -78
  525. package/dist/extensions/pi-subagents/src/watchdog/rules.ts +1 -1
  526. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +107 -31
  527. package/dist/extensions/pi-subagents/src/watchdog/scope.ts +1 -1
  528. package/dist/extensions/pi-subagents/src/watchdog/settings.ts +22 -14
  529. package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +14 -13
  530. package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +35 -6
  531. package/dist/extensions/pi-subagents/src/watchdog/types.ts +6 -4
  532. package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +2 -2
  533. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  534. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +500 -65
  535. package/dist/extensions/pi-subagents/src/workflows/structured-workflow-scripts.ts +177 -0
  536. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +8 -2
  537. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +5 -3
  538. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +70 -10
  539. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +57 -18
  540. package/dist/extensions/pi-subagents/src/workflows/workflow-reuse.ts +120 -0
  541. package/dist/extensions/pi-subagents/src/workflows/workflow-revival.ts +123 -0
  542. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +5 -2
  543. package/dist/extensions/pi-subagents/test/fixtures/cwd-workflow-child.ts +37 -0
  544. package/dist/extensions/pi-subagents/test/fixtures/herdr-allocation-lock-child.ts +16 -0
  545. package/dist/extensions/pi-subagents/test/fixtures/herdr-provision-child.ts +15 -0
  546. package/dist/extensions/pi-subagents/test/fixtures/native-nested-wait-provider.ts +76 -0
  547. package/dist/extensions/pi-subagents/test/fixtures/runner-bootstrap-harness.ts +36 -0
  548. package/dist/extensions/pi-subagents/test/fixtures/schedule-history-writer.mjs +48 -0
  549. package/dist/extensions/pi-subagents/test/fixtures/settings-race-writer.mjs +57 -0
  550. package/dist/extensions/pi-subagents/test/fixtures/workflow-cwd-access-failure.ts +33 -0
  551. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +40 -7
  552. package/dist/extensions/pi-subagents/test/integration/async-attention-clearing.test.ts +9 -8
  553. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +435 -276
  554. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +435 -397
  555. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +918 -497
  556. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +264 -17
  557. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +185 -22
  558. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +3 -2
  559. package/dist/extensions/pi-subagents/test/integration/claude-code-dispatch.test.ts +127 -0
  560. package/dist/extensions/pi-subagents/test/integration/deadline-checkpoint.test.ts +126 -0
  561. package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +29 -1
  562. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +88 -0
  563. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +450 -13
  564. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +10 -6
  565. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +105 -86
  566. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +403 -18
  567. package/dist/extensions/pi-subagents/test/integration/inline-workflow-visibility.test.ts +351 -0
  568. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +195 -10
  569. package/dist/extensions/pi-subagents/test/integration/model-resolution-diagnostic.test.ts +108 -0
  570. package/dist/extensions/pi-subagents/test/integration/nested-async-wait.test.ts +61 -0
  571. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +5 -4
  572. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +1 -1
  573. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +6 -4
  574. package/dist/extensions/pi-subagents/test/integration/render-widget-mouse.test.ts +84 -0
  575. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +242 -16
  576. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +2 -2
  577. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +158 -4
  578. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +1435 -248
  579. package/dist/extensions/pi-subagents/test/integration/single-execution.part-2.test.ts +454 -515
  580. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +140 -21
  581. package/dist/extensions/pi-subagents/test/integration/structured-workflows.test.ts +105 -0
  582. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +90 -11
  583. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +18 -15
  584. package/dist/extensions/pi-subagents/test/integration/workflow-worktree-admission.test.ts +100 -0
  585. package/dist/extensions/pi-subagents/test/smoke/clean-install.mjs +106 -0
  586. package/dist/extensions/pi-subagents/test/smoke/npm-background.mjs +43 -0
  587. package/dist/extensions/pi-subagents/test/smoke/packed-runner-selection.mjs +42 -0
  588. package/dist/extensions/pi-subagents/test/smoke/runner-loader-capability.mjs +50 -0
  589. package/dist/extensions/pi-subagents/test/smoke/sdk-child.ts +57 -0
  590. package/dist/extensions/pi-subagents/test/smoke/{pi085-extension.ts → sdk-extension.ts} +2 -2
  591. package/dist/extensions/pi-subagents/test/smoke/standalone-background.mjs +140 -0
  592. package/dist/extensions/pi-subagents/test/smoke/standalone-fault.ts +43 -0
  593. package/dist/extensions/pi-subagents/test/smoke/standalone-matrix.mjs +65 -0
  594. package/dist/extensions/pi-subagents/test/smoke/standalone-observer.ts +8 -0
  595. package/dist/extensions/pi-subagents/test/smoke/standalone-parent.ts +220 -0
  596. package/dist/extensions/pi-subagents/test/smoke/standalone-provider.ts +58 -0
  597. package/dist/extensions/pi-subagents/test/smoke/standalone-release.json +8 -0
  598. package/dist/extensions/pi-subagents/test/smoke/standalone-revival.ts +109 -0
  599. package/dist/extensions/pi-subagents/test/smoke/standalone-shared.ts +79 -0
  600. package/dist/extensions/pi-subagents/test/smoke/tool-activation.test.ts +128 -0
  601. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +6 -25
  602. package/dist/extensions/pi-subagents/test/support/async-result-timeout-evidence.ts +61 -0
  603. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +122 -9
  604. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +15 -7
  605. package/dist/extensions/pi-subagents/test/support/helpers.ts +11 -14
  606. package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +21 -3
  607. package/dist/extensions/pi-subagents/test/support/native-peer-loader.mjs +15 -0
  608. package/dist/extensions/pi-subagents/test/support/node-command.ts +29 -6
  609. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +5 -3
  610. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +7 -15
  611. package/dist/extensions/pi-subagents/test/support/watchdog-stable-host-loader.mjs +23 -0
  612. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +3 -3
  613. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +158 -155
  614. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +52 -1
  615. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +21 -17
  616. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +105 -36
  617. package/dist/extensions/pi-subagents/test/unit/advertisement-barrier.test.ts +151 -0
  618. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -2
  619. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +33 -3
  620. package/dist/extensions/pi-subagents/test/unit/agent-end-auto-drain.test.ts +149 -0
  621. package/dist/extensions/pi-subagents/test/unit/agent-exclude-dirs.test.ts +246 -0
  622. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +62 -87
  623. package/dist/extensions/pi-subagents/test/unit/agent-global-root-override.test.ts +86 -0
  624. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +398 -48
  625. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +126 -1
  626. package/dist/extensions/pi-subagents/test/unit/agent-name-resolution.test.ts +75 -0
  627. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +94 -42
  628. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +73 -3
  629. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +428 -2
  630. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +4 -4
  631. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +112 -1
  632. package/dist/extensions/pi-subagents/test/unit/async-result-timeout-evidence.test.ts +53 -0
  633. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +92 -4
  634. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +58 -6
  635. package/dist/extensions/pi-subagents/test/unit/async-run-history.test.ts +123 -0
  636. package/dist/extensions/pi-subagents/test/unit/async-spawn-package-dir.test.ts +203 -0
  637. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +26 -35
  638. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +185 -0
  639. package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +9 -1
  640. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +106 -1
  641. package/dist/extensions/pi-subagents/test/unit/await-async-run.test.ts +202 -0
  642. package/dist/extensions/pi-subagents/test/unit/binary-async-spawn.test.ts +115 -0
  643. package/dist/extensions/pi-subagents/test/unit/binary-pi-spawn.test.ts +27 -0
  644. package/dist/extensions/pi-subagents/test/unit/calendar-schedule.test.ts +70 -0
  645. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +38 -0
  646. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +10 -2
  647. package/dist/extensions/pi-subagents/test/unit/changelog-format.test.ts +11 -0
  648. package/dist/extensions/pi-subagents/test/unit/child-cache-retention.test.ts +87 -0
  649. package/dist/extensions/pi-subagents/test/unit/child-commands.test.ts +243 -0
  650. package/dist/extensions/pi-subagents/test/unit/child-external-job-bridge.test.ts +126 -0
  651. package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +12 -1
  652. package/dist/extensions/pi-subagents/test/unit/child-lifecycle.test.ts +36 -0
  653. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +24 -0
  654. package/dist/extensions/pi-subagents/test/unit/child-session-commands.test.ts +162 -0
  655. package/dist/extensions/pi-subagents/test/unit/child-session-host-sdk.test.ts +226 -0
  656. package/dist/extensions/pi-subagents/test/unit/child-session-parent-providers.test.ts +200 -0
  657. package/dist/extensions/pi-subagents/test/unit/child-session-queued.test.ts +260 -0
  658. package/dist/extensions/pi-subagents/test/unit/child-tool-plan-permission-system.test.ts +3 -98
  659. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +222 -1
  660. package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +314 -0
  661. package/dist/extensions/pi-subagents/test/unit/claude-code-dispatch.test.ts +182 -0
  662. package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +157 -0
  663. package/dist/extensions/pi-subagents/test/unit/command-action.test.ts +50 -0
  664. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +25 -11
  665. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +3 -1
  666. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +18 -0
  667. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +7 -1
  668. package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +220 -0
  669. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +104 -32
  670. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +138 -1
  671. package/dist/extensions/pi-subagents/test/unit/disabled-features.test.ts +227 -0
  672. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +48 -9
  673. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +7 -4
  674. package/dist/extensions/pi-subagents/test/unit/extension-lazy-loading.test.ts +21 -0
  675. package/dist/extensions/pi-subagents/test/unit/extension-maintenance-lifecycle.test.ts +66 -0
  676. package/dist/extensions/pi-subagents/test/unit/extension-module-preload.test.ts +49 -0
  677. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +104 -3
  678. package/dist/extensions/pi-subagents/test/unit/file-lease.test.ts +17 -0
  679. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +316 -0
  680. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +58 -7
  681. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +25 -96
  682. package/dist/extensions/pi-subagents/test/unit/ghostty-inspector.test.ts +92 -0
  683. package/dist/extensions/pi-subagents/test/unit/global-npm-root.test.ts +108 -0
  684. package/dist/extensions/pi-subagents/test/unit/herdr-connection.test.ts +43 -0
  685. package/dist/extensions/pi-subagents/test/unit/herdr-external-adapters.test.ts +89 -0
  686. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +11 -20
  687. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +113 -19
  688. package/dist/extensions/pi-subagents/test/unit/herdr-machine.test.ts +161 -0
  689. package/dist/extensions/pi-subagents/test/unit/herdr-native-placement.test.ts +187 -0
  690. package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +7 -12
  691. package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
  692. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +182 -87
  693. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +68 -49
  694. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +295 -135
  695. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +3 -3
  696. package/dist/extensions/pi-subagents/test/unit/inspector-authority-policy.test.ts +144 -0
  697. package/dist/extensions/pi-subagents/test/unit/inspector-registration.test.ts +128 -0
  698. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +49 -1
  699. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +74 -1
  700. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-resolution.test.ts +112 -0
  701. package/dist/extensions/pi-subagents/test/unit/mission-global-projection.test.ts +215 -0
  702. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +65 -1
  703. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +2 -1
  704. package/dist/extensions/pi-subagents/test/unit/model-resolution-diagnostic.test.ts +78 -0
  705. package/dist/extensions/pi-subagents/test/unit/model-resolution.test.ts +153 -0
  706. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +43 -1
  707. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +1 -21
  708. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +279 -2
  709. package/dist/extensions/pi-subagents/test/unit/nested-control-fanout.test.ts +73 -0
  710. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +297 -3
  711. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +1 -1
  712. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +431 -23
  713. package/dist/extensions/pi-subagents/test/unit/opencode-session-headers.test.ts +32 -0
  714. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +89 -21
  715. package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +31 -1
  716. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +18 -24
  717. package/dist/extensions/pi-subagents/test/unit/parent-wake.test.ts +206 -0
  718. package/dist/extensions/pi-subagents/test/unit/partial-output.test.ts +53 -0
  719. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +216 -32
  720. package/dist/extensions/pi-subagents/test/unit/pi-spawn-host-root.test.ts +82 -0
  721. package/dist/extensions/pi-subagents/test/unit/pi-subagents-policy-guidance.test.ts +28 -0
  722. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +193 -104
  723. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +16 -1
  724. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +17 -1
  725. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +89 -9
  726. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +6 -0
  727. package/dist/extensions/pi-subagents/test/unit/prompt-audit-provider-routing.test.ts +69 -0
  728. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +2 -2
  729. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +23 -1
  730. package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +117 -3
  731. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +35 -14
  732. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +3 -2
  733. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +261 -9
  734. package/dist/extensions/pi-subagents/test/unit/reply-workflow-script.test.ts +37 -0
  735. package/dist/extensions/pi-subagents/test/unit/required-child-extensions.test.ts +114 -0
  736. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +11 -1
  737. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +22 -2
  738. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +125 -18
  739. package/dist/extensions/pi-subagents/test/unit/run-child-session.test.ts +230 -0
  740. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +50 -1
  741. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +301 -4
  742. package/dist/extensions/pi-subagents/test/unit/runner-bootstrap.test.ts +182 -0
  743. package/dist/extensions/pi-subagents/test/unit/runner-http-dispatcher.test.ts +136 -0
  744. package/dist/extensions/pi-subagents/test/unit/runner-peer-loader.test.ts +68 -0
  745. package/dist/extensions/pi-subagents/test/unit/runner-peer-symlinks.test.ts +50 -0
  746. package/dist/extensions/pi-subagents/test/unit/running-tone.test.ts +13 -0
  747. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +155 -4
  748. package/dist/extensions/pi-subagents/test/unit/schedule-claim-initialization.test.ts +71 -0
  749. package/dist/extensions/pi-subagents/test/unit/schedule-claim-preservation.test.ts +98 -0
  750. package/dist/extensions/pi-subagents/test/unit/schedule-history-transactions.test.ts +201 -0
  751. package/dist/extensions/pi-subagents/test/unit/scheduled-mission.test.ts +317 -0
  752. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +412 -11
  753. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +2 -8
  754. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +70 -71
  755. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +748 -5
  756. package/dist/extensions/pi-subagents/test/unit/session-liveness-delivery.test.ts +337 -0
  757. package/dist/extensions/pi-subagents/test/unit/settings-atomic-save.test.ts +419 -0
  758. package/dist/extensions/pi-subagents/test/unit/settings-transactions.test.ts +88 -0
  759. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +13 -1
  760. package/dist/extensions/pi-subagents/test/unit/skills-disable-model-invocation.test.ts +164 -0
  761. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +35 -2
  762. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +2 -2
  763. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +334 -9
  764. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +170 -0
  765. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +34 -5
  766. package/dist/extensions/pi-subagents/test/unit/structured-output-validation.test.ts +199 -0
  767. package/dist/extensions/pi-subagents/test/unit/structured-workflow-resources.test.ts +241 -0
  768. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +47 -38
  769. package/dist/extensions/pi-subagents/test/unit/subagent-cost.test.ts +97 -0
  770. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +10 -0
  771. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +343 -44
  772. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +410 -11
  773. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +459 -22
  774. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +43 -3
  775. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +11 -1
  776. package/dist/extensions/pi-subagents/test/unit/tool-activation-stale-peer.test.ts +32 -0
  777. package/dist/extensions/pi-subagents/test/unit/tool-activation.test.ts +313 -0
  778. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +14 -0
  779. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -89
  780. package/dist/extensions/pi-subagents/test/unit/typed-gate-output.test.ts +141 -0
  781. package/dist/extensions/pi-subagents/test/unit/upgrade-notice.test.ts +31 -0
  782. package/dist/extensions/pi-subagents/test/unit/usage-reconciliation-owners.test.ts +66 -0
  783. package/dist/extensions/pi-subagents/test/unit/usage-reconciliation.test.ts +23 -0
  784. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +195 -1
  785. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +3 -1
  786. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +48 -45
  787. package/dist/extensions/pi-subagents/test/unit/watchdog-compaction-scope.test.ts +94 -0
  788. package/dist/extensions/pi-subagents/test/unit/watchdog-diff-tool.test.ts +48 -3
  789. package/dist/extensions/pi-subagents/test/unit/watchdog-native-scheduling.test.ts +107 -0
  790. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +95 -7
  791. package/dist/extensions/pi-subagents/test/unit/watchdog-register-child.test.ts +79 -0
  792. package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +7 -4
  793. package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +111 -24
  794. package/dist/extensions/pi-subagents/test/unit/watchdog-rules.test.ts +1 -1
  795. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +283 -2
  796. package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +3 -0
  797. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +12 -1
  798. package/dist/extensions/pi-subagents/test/unit/watchdog-stable-host-layout.test.ts +23 -0
  799. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +30 -0
  800. package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +39 -2
  801. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +18 -1
  802. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +8 -4
  803. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +10 -0
  804. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +6 -3
  805. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +44 -1
  806. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +28 -1
  807. package/dist/extensions/pi-subagents/test/unit/workflow-revival.test.ts +85 -0
  808. package/dist/extensions/pi-subagents/test/unit/workflow-scripts-feature.test.ts +177 -0
  809. package/dist/extensions/pi-subagents/test/unit/workflow-terminal-proof.test.ts +8 -0
  810. package/dist/extensions/pi-subagents/test/unit/workflow-worktree-admission.test.ts +29 -0
  811. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +343 -4
  812. package/dist/extensions/pi-subagents/test/unit/worktree-lock.test.ts +123 -0
  813. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +252 -22
  814. package/dist/extensions/pi-subagents/tsconfig.build.json +13 -0
  815. package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +1 -1
  816. package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +1 -1
  817. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +24 -1
  818. package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +6 -2
  819. package/dist/extensions/pi-web-agent/src/extension.ts +1 -5
  820. package/dist/extensions/pi-zentui/.github/workflows/ci.yml +67 -4
  821. package/dist/extensions/pi-zentui/AGENTS.md +3 -2
  822. package/dist/extensions/pi-zentui/README.md +60 -32
  823. package/dist/extensions/pi-zentui/docs/configuration.md +662 -51
  824. package/dist/extensions/pi-zentui/docs/footer-format.md +174 -5
  825. package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-editor.ts +15 -4
  826. package/dist/extensions/pi-zentui/extensions/zentui/average-token-rate.ts +146 -0
  827. package/dist/extensions/pi-zentui/extensions/zentui/codex-quota-display.ts +34 -0
  828. package/dist/extensions/pi-zentui/extensions/zentui/codex-quota.ts +298 -0
  829. package/dist/extensions/pi-zentui/extensions/zentui/component-colors.ts +172 -0
  830. package/dist/extensions/pi-zentui/extensions/zentui/component-settings.ts +243 -0
  831. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +851 -114
  832. package/dist/extensions/pi-zentui/extensions/zentui/custom-value-colors.ts +93 -0
  833. package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-demand.ts +61 -0
  834. package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-format.ts +80 -0
  835. package/dist/extensions/pi-zentui/extensions/zentui/custom-variables.ts +152 -0
  836. package/dist/extensions/pi-zentui/extensions/zentui/editor-metadata-format.ts +138 -23
  837. package/dist/extensions/pi-zentui/extensions/zentui/editor-mouse.ts +89 -0
  838. package/dist/extensions/pi-zentui/extensions/zentui/extension-status-controller.ts +148 -0
  839. package/dist/extensions/pi-zentui/extensions/zentui/extension-status-settings.ts +40 -0
  840. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +109 -1
  841. package/dist/extensions/pi-zentui/extensions/zentui/footer-format.ts +203 -23
  842. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +80 -3
  843. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +1 -1
  844. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +432 -125
  845. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +92 -4
  846. package/dist/extensions/pi-zentui/extensions/zentui/git.ts +47 -30
  847. package/dist/extensions/pi-zentui/extensions/zentui/github-status.ts +575 -0
  848. package/dist/extensions/pi-zentui/extensions/zentui/host-project-changes.ts +25 -0
  849. package/dist/extensions/pi-zentui/extensions/zentui/host-template-values.ts +29 -0
  850. package/dist/extensions/pi-zentui/extensions/zentui/icons.ts +53 -13
  851. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +778 -258
  852. package/dist/extensions/pi-zentui/extensions/zentui/interaction-summary.ts +70 -5
  853. package/dist/extensions/pi-zentui/extensions/zentui/layered-editor.ts +55 -0
  854. package/dist/extensions/pi-zentui/extensions/zentui/live-context.ts +6 -1
  855. package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-demand.ts +72 -0
  856. package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-display.ts +21 -0
  857. package/dist/extensions/pi-zentui/extensions/zentui/live-metadata.ts +255 -0
  858. package/dist/extensions/pi-zentui/extensions/zentui/minimalist-editor.ts +476 -36
  859. package/dist/extensions/pi-zentui/extensions/zentui/minimalist-settings.ts +118 -0
  860. package/dist/extensions/pi-zentui/extensions/zentui/minimalist-template.ts +177 -0
  861. package/dist/extensions/pi-zentui/extensions/zentui/omp-editor-frame.ts +148 -0
  862. package/dist/extensions/pi-zentui/extensions/zentui/omp-statusline.ts +569 -0
  863. package/dist/extensions/pi-zentui/extensions/zentui/omp-template-lookups.ts +344 -0
  864. package/dist/extensions/pi-zentui/extensions/zentui/omp-template-metrics.ts +91 -0
  865. package/dist/extensions/pi-zentui/extensions/zentui/omp-template-modes.ts +323 -0
  866. package/dist/extensions/pi-zentui/extensions/zentui/omp-ui.ts +210 -0
  867. package/dist/extensions/pi-zentui/extensions/zentui/package-version.ts +30 -12
  868. package/dist/extensions/pi-zentui/extensions/zentui/project-demand.ts +46 -0
  869. package/dist/extensions/pi-zentui/extensions/zentui/project-discovery.ts +58 -0
  870. package/dist/extensions/pi-zentui/extensions/zentui/project-refresh.ts +10 -3
  871. package/dist/extensions/pi-zentui/extensions/zentui/project-state.ts +37 -0
  872. package/dist/extensions/pi-zentui/extensions/zentui/repository-root.ts +1 -0
  873. package/dist/extensions/pi-zentui/extensions/zentui/runtime.ts +119 -43
  874. package/dist/extensions/pi-zentui/extensions/zentui/selector-border.ts +40 -29
  875. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +1268 -722
  876. package/dist/extensions/pi-zentui/extensions/zentui/settings-keys.ts +59 -0
  877. package/dist/extensions/pi-zentui/extensions/zentui/settings-list-selection.ts +13 -0
  878. package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +11 -4
  879. package/dist/extensions/pi-zentui/extensions/zentui/state.ts +24 -11
  880. package/dist/extensions/pi-zentui/extensions/zentui/style.ts +6 -0
  881. package/dist/extensions/pi-zentui/extensions/zentui/telemetry.ts +113 -11
  882. package/dist/extensions/pi-zentui/extensions/zentui/thinking-experimental.ts +234 -46
  883. package/dist/extensions/pi-zentui/extensions/zentui/thinking-steps.ts +20 -5
  884. package/dist/extensions/pi-zentui/extensions/zentui/token-rate.ts +313 -0
  885. package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-format.ts +59 -0
  886. package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-rate.ts +52 -0
  887. package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +640 -172
  888. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +72 -34
  889. package/dist/extensions/pi-zentui/extensions/zentui/user-message.ts +219 -34
  890. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +495 -119
  891. package/dist/extensions/pi-zentui/omp.ts +157 -0
  892. package/dist/extensions/pi-zentui/package-lock.json +3762 -1507
  893. package/dist/extensions/pi-zentui/package.json +50 -12
  894. package/dist/extensions/pi-zentui/test/accent-rail-editor.test.ts +13 -2
  895. package/dist/extensions/pi-zentui/test/average-token-rate.test.ts +297 -0
  896. package/dist/extensions/pi-zentui/test/behavior-compatibility.mjs +89 -0
  897. package/dist/extensions/pi-zentui/test/codex-quota-lifecycle.test.ts +284 -0
  898. package/dist/extensions/pi-zentui/test/codex-quota-rendering.test.ts +466 -0
  899. package/dist/extensions/pi-zentui/test/codex-quota.test.ts +440 -0
  900. package/dist/extensions/pi-zentui/test/component-colors.test.ts +554 -0
  901. package/dist/extensions/pi-zentui/test/component-settings.test.ts +364 -0
  902. package/dist/extensions/pi-zentui/test/config-component-independence.test.ts +402 -0
  903. package/dist/extensions/pi-zentui/test/config-extension-status-choice.test.ts +233 -0
  904. package/dist/extensions/pi-zentui/test/config-hidden-extension-status-colors.test.ts +118 -0
  905. package/dist/extensions/pi-zentui/test/config-hidden-extension-status-placement.test.ts +142 -0
  906. package/dist/extensions/pi-zentui/test/config-minimalist-templates.test.ts +240 -0
  907. package/dist/extensions/pi-zentui/test/config-template-variables.test.ts +85 -0
  908. package/dist/extensions/pi-zentui/test/config.test.ts +80 -17
  909. package/dist/extensions/pi-zentui/test/custom-value-colors-integration.test.ts +453 -0
  910. package/dist/extensions/pi-zentui/test/custom-value-colors.test.ts +399 -0
  911. package/dist/extensions/pi-zentui/test/custom-variable-alias-prototypes.test.ts +177 -0
  912. package/dist/extensions/pi-zentui/test/custom-variable-consumers.test.ts +194 -0
  913. package/dist/extensions/pi-zentui/test/custom-variable-demand.test.ts +169 -0
  914. package/dist/extensions/pi-zentui/test/custom-variable-probe-reservation.test.ts +141 -0
  915. package/dist/extensions/pi-zentui/test/custom-variables-lifecycle.integration.test.ts +365 -0
  916. package/dist/extensions/pi-zentui/test/custom-variables.test.ts +330 -0
  917. package/dist/extensions/pi-zentui/test/editor-metadata-format.test.ts +121 -0
  918. package/dist/extensions/pi-zentui/test/editor-mouse.test.ts +507 -0
  919. package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +247 -20
  920. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +204 -260
  921. package/dist/extensions/pi-zentui/test/extension-status-controller.test.ts +323 -0
  922. package/dist/extensions/pi-zentui/test/extension-status-lifecycle.integration.test.ts +466 -0
  923. package/dist/extensions/pi-zentui/test/extension-status-settings.test.ts +79 -0
  924. package/dist/extensions/pi-zentui/test/footer-alignment.test.ts +135 -0
  925. package/dist/extensions/pi-zentui/test/footer-authority.test.ts +69 -0
  926. package/dist/extensions/pi-zentui/test/footer-auto-compaction.test.ts +148 -0
  927. package/dist/extensions/pi-zentui/test/footer-format-cache.test.ts +186 -0
  928. package/dist/extensions/pi-zentui/test/footer-format.test.ts +154 -4
  929. package/dist/extensions/pi-zentui/test/footer-hidden.test.ts +312 -0
  930. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +22 -0
  931. package/dist/extensions/pi-zentui/test/footer-layout.test.ts +80 -0
  932. package/dist/extensions/pi-zentui/test/footer-thinking-level.test.ts +123 -0
  933. package/dist/extensions/pi-zentui/test/format.test.ts +75 -1
  934. package/dist/extensions/pi-zentui/test/git-probes.test.ts +182 -0
  935. package/dist/extensions/pi-zentui/test/github-status.test.ts +931 -0
  936. package/dist/extensions/pi-zentui/test/host-template-surfaces.test.ts +287 -0
  937. package/dist/extensions/pi-zentui/test/icons.test.ts +86 -16
  938. package/dist/extensions/pi-zentui/test/layered-editor.test.ts +53 -0
  939. package/dist/extensions/pi-zentui/test/live-context-integration.test.ts +154 -7
  940. package/dist/extensions/pi-zentui/test/live-context.test.ts +45 -0
  941. package/dist/extensions/pi-zentui/test/live-metadata-lifecycle.integration.test.ts +963 -0
  942. package/dist/extensions/pi-zentui/test/live-metadata.test.ts +767 -0
  943. package/dist/extensions/pi-zentui/test/minimalist-cache-hit-colors.test.ts +183 -0
  944. package/dist/extensions/pi-zentui/test/minimalist-editor.test.ts +222 -4
  945. package/dist/extensions/pi-zentui/test/minimalist-settings.test.ts +103 -0
  946. package/dist/extensions/pi-zentui/test/minimalist-templates.test.ts +489 -0
  947. package/dist/extensions/pi-zentui/test/omp-editor-composers.test.ts +324 -0
  948. package/dist/extensions/pi-zentui/test/omp-statusline.test.ts +579 -0
  949. package/dist/extensions/pi-zentui/test/omp-template-lookups.test.ts +630 -0
  950. package/dist/extensions/pi-zentui/test/omp-template-metrics.test.ts +72 -0
  951. package/dist/extensions/pi-zentui/test/omp-template-modes.test.ts +557 -0
  952. package/dist/extensions/pi-zentui/test/omp-ui.test.ts +93 -0
  953. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  954. package/dist/extensions/pi-zentui/test/pi-version-policy.test.ts +37 -0
  955. package/dist/extensions/pi-zentui/test/project-demand-integration.test.ts +542 -0
  956. package/dist/extensions/pi-zentui/test/project-discovery.test.ts +412 -0
  957. package/dist/extensions/pi-zentui/test/project-refresh.test.ts +44 -0
  958. package/dist/extensions/pi-zentui/test/project-state.test.ts +38 -1
  959. package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +7 -7
  960. package/dist/extensions/pi-zentui/test/runtime.test.ts +127 -2
  961. package/dist/extensions/pi-zentui/test/selesai-v030-gate.json +939 -0
  962. package/dist/extensions/pi-zentui/test/settings-command.test.ts +1330 -82
  963. package/dist/extensions/pi-zentui/test/settings-keys.test.ts +41 -0
  964. package/dist/extensions/pi-zentui/test/settings-list-selection.test.ts +88 -0
  965. package/dist/extensions/pi-zentui/test/settings-previews.test.ts +4 -1
  966. package/dist/extensions/pi-zentui/test/state.test.ts +15 -1
  967. package/dist/extensions/pi-zentui/test/telemetry-lifecycle-integration.test.ts +214 -12
  968. package/dist/extensions/pi-zentui/test/telemetry-snapshot.test.ts +246 -0
  969. package/dist/extensions/pi-zentui/test/thinking-experimental-cache.test.ts +246 -0
  970. package/dist/extensions/pi-zentui/test/thinking-experimental-rows.test.ts +22 -0
  971. package/dist/extensions/pi-zentui/test/thinking-experimental-tui.mjs +113 -51
  972. package/dist/extensions/pi-zentui/test/thinking-experimental.test.ts +576 -76
  973. package/dist/extensions/pi-zentui/test/thinking-steps.test.ts +23 -0
  974. package/dist/extensions/pi-zentui/test/token-rate.test.ts +450 -0
  975. package/dist/extensions/pi-zentui/test/turn-summary-format.test.ts +207 -0
  976. package/dist/extensions/pi-zentui/test/turn-summary-lifecycle.integration.test.ts +72 -5
  977. package/dist/extensions/pi-zentui/test/turn-summary-rate.test.ts +158 -0
  978. package/dist/extensions/pi-zentui/test/usage-lifecycle-integration.test.ts +421 -0
  979. package/dist/extensions/pi-zentui/test/usage-snapshot.test.ts +154 -0
  980. package/dist/extensions/pi-zentui/test/user-message-cache.test.ts +239 -0
  981. package/dist/extensions/pi-zentui/test/user-message-native-reduced-capabilities.test.ts +61 -0
  982. package/dist/extensions/pi-zentui/test/user-message-native.test.ts +447 -0
  983. package/dist/extensions/pi-zentui/test/user-message-styles.test.ts +2 -2
  984. package/dist/extensions/pi-zentui/test/working-line-editor-placement.test.ts +317 -0
  985. package/dist/extensions/pi-zentui/test/working-line-generation-cache.test.ts +238 -0
  986. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +674 -179
  987. package/dist/extensions/pi-zentui/test/working-line-message-ownership.test.ts +239 -0
  988. package/dist/extensions/pi-zentui/test/working-line-metric-animation.test.ts +284 -0
  989. package/dist/extensions/pi-zentui/test/working-line-placement.test.ts +298 -0
  990. package/dist/extensions/pi-zentui/test/working-line.test.ts +386 -18
  991. package/dist/extensions/pi-zentui/test/wrapped-editor-consumers.integration.test.ts +579 -0
  992. package/dist/extensions/pi-zentui/test/wrapped-editor-usage.integration.test.ts +298 -0
  993. package/dist/extensions/pi-zentui/tsconfig.json +1 -1
  994. package/dist/extensions/pi-zentui/vitest.host.config.ts +33 -0
  995. package/dist/extensions/question/index.ts +1 -5
  996. package/dist/extensions/rtk.test.ts +28 -15
  997. package/dist/extensions/rtk.ts +22 -22
  998. package/dist/extensions/skills-index/index.test.ts +99 -0
  999. package/dist/extensions/skills-index/index.ts +105 -0
  1000. package/dist/extensions/skills-index/package.json +9 -0
  1001. package/dist/extensions/tokenin-onboarding.ts +48 -208
  1002. package/dist/extensions/tool-search/index.d.ts +11 -0
  1003. package/dist/extensions/tool-search/index.js +14 -0
  1004. package/dist/extensions/tool-search/tool.d.ts +91 -0
  1005. package/dist/extensions/tool-search/tool.js +214 -0
  1006. package/dist/index.d.ts +17 -9
  1007. package/dist/index.js +11 -5
  1008. package/dist/main.d.ts +4 -0
  1009. package/dist/main.js +106 -42
  1010. package/dist/migrations.js +4 -3
  1011. package/dist/modes/index.d.ts +1 -0
  1012. package/dist/modes/interactive/bug-report.js +4 -0
  1013. package/dist/modes/interactive/components/armin.d.ts +3 -0
  1014. package/dist/modes/interactive/components/armin.js +7 -5
  1015. package/dist/modes/interactive/components/assistant-message.js +1 -1
  1016. package/dist/modes/interactive/components/auth-url.d.ts +13 -0
  1017. package/dist/modes/interactive/components/auth-url.js +36 -0
  1018. package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
  1019. package/dist/modes/interactive/components/bash-execution.js +17 -14
  1020. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  1021. package/dist/modes/interactive/components/branch-summary-message.js +5 -2
  1022. package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
  1023. package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
  1024. package/dist/modes/interactive/components/config-selector.js +13 -3
  1025. package/dist/modes/interactive/components/custom-editor.js +7 -0
  1026. package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
  1027. package/dist/modes/interactive/components/custom-entry.js +8 -2
  1028. package/dist/modes/interactive/components/custom-message.js +1 -0
  1029. package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
  1030. package/dist/modes/interactive/components/first-time-setup.js +8 -2
  1031. package/dist/modes/interactive/components/footer.d.ts +7 -0
  1032. package/dist/modes/interactive/components/footer.js +44 -4
  1033. package/dist/modes/interactive/components/index.d.ts +0 -1
  1034. package/dist/modes/interactive/components/index.js +0 -1
  1035. package/dist/modes/interactive/components/login-dialog.d.ts +2 -0
  1036. package/dist/modes/interactive/components/login-dialog.js +11 -5
  1037. package/dist/modes/interactive/components/mermaid.d.ts +10 -0
  1038. package/dist/modes/interactive/components/mermaid.js +74 -0
  1039. package/dist/modes/interactive/components/model-selector.d.ts +14 -9
  1040. package/dist/modes/interactive/components/model-selector.js +79 -31
  1041. package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
  1042. package/dist/modes/interactive/components/oauth-selector.js +24 -21
  1043. package/dist/modes/interactive/components/pi-logo.d.ts +18 -0
  1044. package/dist/modes/interactive/components/pi-logo.js +36 -0
  1045. package/dist/modes/interactive/components/radius-login-selector.d.ts +14 -0
  1046. package/dist/modes/interactive/components/radius-login-selector.js +84 -0
  1047. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  1048. package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
  1049. package/dist/modes/interactive/components/settings-selector.d.ts +8 -11
  1050. package/dist/modes/interactive/components/settings-selector.js +60 -102
  1051. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  1052. package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
  1053. package/dist/modes/interactive/components/themed-text.d.ts +16 -0
  1054. package/dist/modes/interactive/components/themed-text.js +28 -0
  1055. package/dist/modes/interactive/components/tool-execution.d.ts +11 -18
  1056. package/dist/modes/interactive/components/tool-execution.js +34 -47
  1057. package/dist/modes/interactive/components/tree-selector.js +7 -0
  1058. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  1059. package/dist/modes/interactive/components/user-message.js +14 -6
  1060. package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
  1061. package/dist/modes/interactive/components/visual-truncate.js +39 -6
  1062. package/dist/modes/interactive/external-editor.js +2 -1
  1063. package/dist/modes/interactive/interactive-mode.d.ts +41 -8
  1064. package/dist/modes/interactive/interactive-mode.js +854 -492
  1065. package/dist/modes/interactive/program-status-reporter.d.ts +33 -0
  1066. package/dist/modes/interactive/program-status-reporter.js +109 -0
  1067. package/dist/modes/interactive/theme/dark.json +59 -72
  1068. package/dist/modes/interactive/theme/light.json +57 -69
  1069. package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
  1070. package/dist/modes/interactive/theme/system-theme.js +545 -0
  1071. package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
  1072. package/dist/modes/interactive/theme/theme-controller.js +127 -47
  1073. package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
  1074. package/dist/modes/interactive/theme/theme-json.js +3 -1
  1075. package/dist/modes/interactive/theme/theme-schema.json +7 -2
  1076. package/dist/modes/interactive/theme/theme.d.ts +66 -39
  1077. package/dist/modes/interactive/theme/theme.js +243 -320
  1078. package/dist/modes/interactive/tui-renderer.d.ts +2 -1
  1079. package/dist/modes/interactive/tui-renderer.js +1 -0
  1080. package/dist/modes/json-event.d.ts +33 -0
  1081. package/dist/modes/json-event.js +28 -0
  1082. package/dist/modes/print-mode.js +12 -2
  1083. package/dist/modes/rpc/rpc-client.d.ts +11 -19
  1084. package/dist/modes/rpc/rpc-client.js +52 -35
  1085. package/dist/modes/rpc/rpc-mode.js +11 -26
  1086. package/dist/modes/rpc/rpc-types.d.ts +12 -23
  1087. package/dist/package-manager-cli.js +16 -5
  1088. package/dist/rpc-entry.js +1 -0
  1089. package/dist/skills/pi-subagents/SKILL.md +109 -35
  1090. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +38 -238
  1091. package/dist/skills/pi-subagents/references/execution-controls.md +181 -83
  1092. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -9
  1093. package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +24 -2
  1094. package/dist/skills/pi-subagents/references/prompting-and-roles.md +121 -91
  1095. package/dist/skills/pi-subagents/references/review-and-validation.md +73 -0
  1096. package/dist/utils/ansi.d.ts +8 -0
  1097. package/dist/utils/ansi.js +30 -11
  1098. package/dist/utils/clipboard-image.js +14 -17
  1099. package/dist/utils/clipboard.d.ts +2 -0
  1100. package/dist/utils/clipboard.js +17 -11
  1101. package/dist/utils/frontmatter.js +2 -1
  1102. package/dist/utils/image-convert.d.ts +12 -0
  1103. package/dist/utils/image-convert.js +45 -6
  1104. package/dist/utils/image-resize-core.d.ts +12 -0
  1105. package/dist/utils/image-resize-core.js +5 -0
  1106. package/dist/utils/image-resize-worker.js +3 -2
  1107. package/dist/utils/image-resize.js +9 -10
  1108. package/dist/utils/mime.js +1 -1
  1109. package/dist/utils/output-files.d.ts +14 -0
  1110. package/dist/utils/output-files.js +29 -0
  1111. package/dist/utils/paths.d.ts +6 -3
  1112. package/dist/utils/paths.js +28 -5
  1113. package/dist/utils/shell.d.ts +1 -3
  1114. package/dist/utils/shell.js +3 -30
  1115. package/dist/utils/syntax-highlight.d.ts +1 -0
  1116. package/dist/utils/syntax-highlight.js +68 -2
  1117. package/dist/utils/tool-result-images.d.ts +20 -0
  1118. package/dist/utils/tool-result-images.js +47 -0
  1119. package/dist/utils/tools-manager.d.ts +5 -0
  1120. package/dist/utils/tools-manager.js +6 -6
  1121. package/dist/utils/version-check.d.ts +4 -0
  1122. package/dist/utils/version-check.js +20 -2
  1123. package/docs/cli-integration.md +104 -0
  1124. package/docs/cli.md +333 -0
  1125. package/docs/codemode.md +230 -0
  1126. package/docs/configuration.md +47 -0
  1127. package/docs/environment-variables.md +5 -0
  1128. package/docs/extensions.md +107 -30
  1129. package/docs/json.md +8 -4
  1130. package/docs/keybindings.md +10 -10
  1131. package/docs/mcp.md +262 -0
  1132. package/docs/models.md +104 -3
  1133. package/docs/providers.md +20 -2
  1134. package/docs/rpc.md +13 -12
  1135. package/docs/sdk.md +41 -33
  1136. package/docs/security.md +21 -20
  1137. package/docs/settings.md +18 -46
  1138. package/docs/terminal-setup.md +14 -0
  1139. package/docs/virtual-models.md +114 -0
  1140. package/examples/extensions/jev-router.ts +113 -0
  1141. package/examples/extensions/tokenin-usage-widget.ts +124 -0
  1142. package/examples/rpc-client.ts +35 -0
  1143. package/examples/sdk/14-codemode-mcp.ts +67 -0
  1144. package/package.json +15 -8
  1145. package/dist/core/agent-session-auto-handoff.test.js +0 -195
  1146. package/dist/core/built-in-extensions.d.ts +0 -2
  1147. package/dist/core/built-in-extensions.js +0 -2
  1148. package/dist/core/llama/provider.js +0 -143
  1149. package/dist/core/settings-manager-auto-handoff.test.d.ts +0 -1
  1150. package/dist/core/settings-manager-auto-handoff.test.js +0 -53
  1151. package/dist/extensions/capability-gateway/catalog.ts +0 -177
  1152. package/dist/extensions/capability-gateway/index.test.ts +0 -226
  1153. package/dist/extensions/capability-gateway/index.ts +0 -669
  1154. package/dist/extensions/capability-gateway/integration.test.ts +0 -803
  1155. package/dist/extensions/capability-gateway/package.json +0 -16
  1156. package/dist/extensions/capability-gateway/routing.test.ts +0 -574
  1157. package/dist/extensions/capability-gateway/routing.ts +0 -403
  1158. package/dist/extensions/pi-subagents/runner-server-preload.mjs +0 -13
  1159. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +0 -89
  1160. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +0 -259
  1161. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +0 -312
  1162. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +0 -374
  1163. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +0 -69
  1164. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +0 -307
  1165. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +0 -211
  1166. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +0 -3
  1167. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +0 -2
  1168. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +0 -17
  1169. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +0 -57
  1170. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +0 -16
  1171. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +0 -15
  1172. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +0 -18
  1173. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +0 -9
  1174. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +0 -10
  1175. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +0 -10
  1176. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +0 -20
  1177. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +0 -3
  1178. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +0 -96
  1179. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +0 -119
  1180. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +0 -85
  1181. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +0 -620
  1182. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +0 -5
  1183. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +0 -56
  1184. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +0 -32
  1185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +0 -49
  1186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +0 -93
  1187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +0 -128
  1188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +0 -7
  1189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +0 -38
  1190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +0 -3
  1191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +0 -15
  1192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +0 -9
  1193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +0 -29
  1194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +0 -2
  1195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +0 -22
  1196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +0 -37
  1197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +0 -34
  1198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +0 -12
  1199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +0 -23
  1200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +0 -171
  1201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +0 -1261
  1202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +0 -20
  1203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +0 -54
  1204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +0 -22
  1205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +0 -13
  1206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +0 -358
  1207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +0 -77
  1208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +0 -512
  1209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +0 -43
  1210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +0 -121
  1211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +0 -82
  1212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +0 -17
  1213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +0 -7
  1214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +0 -210
  1215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +0 -15
  1216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +0 -54
  1217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +0 -4
  1218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +0 -55
  1219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +0 -2
  1220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +0 -5
  1221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +0 -30
  1222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +0 -206
  1223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +0 -15
  1224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +0 -106
  1225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +0 -19
  1226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +0 -356
  1227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +0 -297
  1228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +0 -60
  1229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +0 -15
  1230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +0 -18
  1231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +0 -28
  1232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +0 -3
  1233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +0 -10
  1234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +0 -68
  1235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +0 -106
  1236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +0 -51
  1237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +0 -6
  1238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +0 -35
  1239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +0 -37
  1240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +0 -40
  1241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +0 -37
  1242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +0 -52
  1243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +0 -10
  1244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +0 -35
  1245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +0 -24
  1246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +0 -14
  1247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +0 -70
  1248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +0 -26
  1249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +0 -36
  1250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +0 -19
  1251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +0 -61
  1252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +0 -23
  1253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +0 -3
  1254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +0 -10
  1255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +0 -42
  1256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +0 -35
  1257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +0 -12
  1258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +0 -33
  1259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +0 -9
  1260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +0 -34
  1261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +0 -22
  1262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +0 -34
  1263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +0 -16
  1264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +0 -16
  1265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
  1266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +0 -102
  1267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +0 -14
  1268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +0 -21
  1269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +0 -19
  1270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +0 -20
  1271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +0 -23
  1272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +0 -12
  1273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +0 -15
  1274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +0 -5
  1275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +0 -22
  1276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +0 -23
  1277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +0 -26
  1278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +0 -25
  1279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +0 -32
  1280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +0 -34
  1281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +0 -13
  1282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +0 -52
  1283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +0 -54
  1284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +0 -33
  1285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -42
  1286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +0 -23
  1287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +0 -95
  1288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +0 -77
  1289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +0 -10
  1290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -17
  1291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +0 -28
  1292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +0 -11
  1293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +0 -11
  1294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +0 -63
  1295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +0 -94
  1296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +0 -23
  1297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +0 -30
  1298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +0 -14
  1299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +0 -24
  1300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +0 -394
  1301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +0 -12
  1302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +0 -29
  1303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +0 -120
  1304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +0 -28
  1305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +0 -17
  1306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +0 -246
  1307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +0 -20
  1308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +0 -457
  1309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +0 -8
  1310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +0 -3
  1311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +0 -2
  1312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +0 -22
  1313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +0 -18
  1314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +0 -11
  1315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +0 -11
  1316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +0 -4
  1317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +0 -4
  1318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +0 -5
  1319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +0 -8
  1320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +0 -5
  1321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +0 -26
  1322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +0 -7
  1323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +0 -10
  1324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +0 -18
  1325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +0 -30
  1326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +0 -2
  1327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +0 -16
  1328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +0 -3
  1329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +0 -3
  1330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +0 -9
  1331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +0 -31
  1332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +0 -21
  1333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +0 -2
  1334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +0 -31
  1335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +0 -5
  1336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +0 -12
  1337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +0 -3
  1338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +0 -15
  1339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +0 -3
  1340. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +0 -31
  1341. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +0 -74
  1342. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +0 -150
  1343. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +0 -766
  1344. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +0 -327
  1345. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +0 -309
  1346. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +0 -1093
  1347. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +0 -94
  1348. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +0 -1329
  1349. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +0 -153
  1350. package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-layout-patch.ts +0 -457
  1351. package/dist/extensions/pi-zentui/test/accent-rail-layout-patch.test.ts +0 -669
  1352. package/dist/extensions/pi-zentui/test/thinking-experimental-docs.test.ts +0 -51
  1353. package/dist/modes/interactive/components/daxnuts.d.ts +0 -22
  1354. package/dist/modes/interactive/components/daxnuts.js +0 -139
  1355. /package/dist/core/{agent-session-auto-handoff.test.d.ts → agent-session-custom-tools.test.d.ts} +0 -0
  1356. /package/dist/{core → extensions}/llama/huggingface.d.ts +0 -0
  1357. /package/dist/{core → extensions}/llama/huggingface.js +0 -0
  1358. /package/dist/{core → extensions}/llama/index.d.ts +0 -0
  1359. /package/dist/{core → extensions}/llama/ui.d.ts +0 -0
  1360. /package/dist/{core → extensions}/llama/ui.js +0 -0
@@ -1,9 +1,17 @@
1
1
  import type { Theme } from "@earendil-works/pi-coding-agent";
2
- import { visibleWidth } from "@earendil-works/pi-tui";
2
+ import {
3
+ getKeybindings,
4
+ KeybindingsManager,
5
+ setKeybindings,
6
+ TUI_KEYBINDINGS,
7
+ visibleWidth,
8
+ } from "@earendil-works/pi-tui";
3
9
  import { afterEach, describe, expect, it, vi } from "vitest";
10
+ import { renderAccentRailEditorFrame } from "../extensions/zentui/accent-rail-editor";
4
11
  import {
5
12
  defaultConfig,
6
13
  type EditorComponentConfig,
14
+ type ExtensionStatusColorMode,
7
15
  type ExtensionStatusPlacement,
8
16
  type FooterComponentConfig,
9
17
  type PolishedTuiConfig,
@@ -20,7 +28,7 @@ import { registerZentuiSettingsCommand } from "../extensions/zentui/settings-com
20
28
  type Component = { render(width: number): string[]; handleInput(data: string): void };
21
29
  type Command = {
22
30
  handler(args: string, ctx: unknown): Promise<void>;
23
- getArgumentCompletions(prefix: string): Array<{ value: string }> | null;
31
+ getArgumentCompletions(prefix: string): Array<{ value: string; label: string }> | null;
24
32
  };
25
33
  const sectionNames = [
26
34
  "Appearance",
@@ -29,11 +37,10 @@ const sectionNames = [
29
37
  "Thinking",
30
38
  "Working line",
31
39
  "Footer",
32
- "Segments",
33
- "Git",
34
- "Extensions",
40
+ "Extension statuses",
35
41
  ] as const;
36
- type SectionName = (typeof sectionNames)[number];
42
+ const footerPageNames = ["Segments", "Git"] as const;
43
+ type SectionName = (typeof sectionNames)[number] | (typeof footerPageNames)[number];
37
44
 
38
45
  function theme(): Theme {
39
46
  return {
@@ -66,22 +73,35 @@ function cloneConfig(): PolishedTuiConfig {
66
73
  return config;
67
74
  }
68
75
  function goToSection(component: Component, section: SectionName): void {
69
- for (let index = 0; index < sectionNames.indexOf(section); index += 1)
76
+ if (footerPageNames.some((name) => name === section)) {
77
+ goToSection(component, "Footer");
78
+ openFooterPage(component, section as (typeof footerPageNames)[number]);
79
+ return;
80
+ }
81
+ for (
82
+ let index = 0;
83
+ index < sectionNames.indexOf(section as (typeof sectionNames)[number]);
84
+ index += 1
85
+ )
70
86
  component.handleInput("\t");
71
87
  }
88
+ function openFooterPage(component: Component, page: (typeof footerPageNames)[number]): void {
89
+ selectLabel(component, page);
90
+ component.handleInput("\r");
91
+ }
72
92
  function selectLabel(component: Component, label: string): void {
73
93
  for (let index = 0; index < 40; index += 1) {
74
- if (component.render(160).some((line) => line.includes(`> ${label}`))) return;
94
+ if (component.render(160).some((line) => line.startsWith(`> ${label}`))) return;
75
95
  component.handleInput("\x1b[B");
76
96
  }
77
97
  throw new Error(`Could not select ${label}`);
78
98
  }
79
99
  function row(component: Component, label: string): string {
80
100
  selectLabel(component, label);
81
- return component.render(160).find((line) => line.includes(`> ${label}`)) ?? "";
101
+ return component.render(160).find((line) => line.startsWith(`> ${label}`)) ?? "";
82
102
  }
83
103
  function focusedRow(component: Component): string {
84
- return component.render(200).find((line) => line.includes("> ")) ?? "";
104
+ return component.render(200).find((line) => line.startsWith("> ")) ?? "";
85
105
  }
86
106
  function previewRow(rows: string[], text: string): number {
87
107
  const index = rows.findIndex((line) => line.includes(text));
@@ -91,7 +111,7 @@ function previewRow(rows: string[], text: string): number {
91
111
  function expectStackedPreview(rows: string[], previewText: string): void {
92
112
  const previewIndex = previewRow(rows, previewText);
93
113
  const settingsIndex = rows.findIndex(
94
- (line, index) => index > previewIndex && line.includes("> "),
114
+ (line, index) => index > previewIndex && line.startsWith("> "),
95
115
  );
96
116
  if (settingsIndex < 0) throw new Error("Could not find settings below preview");
97
117
  expect(rows[3]).toBe("");
@@ -128,6 +148,7 @@ function createHarness(
128
148
  const notificationEvents: Array<{ message: string; severity: string }> = [];
129
149
  let doneCalls = 0;
130
150
  const sessionLifecycle = new SessionLifecycle();
151
+ sessionLifecycle.start();
131
152
  const calls = {
132
153
  presets: [] as PresetId[],
133
154
  editor: [] as Partial<EditorComponentConfig>[],
@@ -149,6 +170,8 @@ function createHarness(
149
170
  recipe: [] as boolean[],
150
171
  };
151
172
  const deps = {
173
+ migrateSelections: () => {},
174
+ setComponentColor: () => {},
152
175
  sessionLifecycle,
153
176
  getConfig: () => config,
154
177
  applyPreset(id: PresetId) {
@@ -230,12 +253,60 @@ function createHarness(
230
253
  Object.assign(config.components.footer.styles.starship.gitMetrics, patch);
231
254
  },
232
255
  getActiveExtensionStatuses: () => new Map(),
233
- setExtensionStatusDefaultPlacement(placement: ExtensionStatusPlacement) {
256
+ setExtensionStatusDefaultChoice(placement: ExtensionStatusPlacement) {
234
257
  calls.extensionDefaultPlacement.push(placement);
235
- config.components.footer.styles.starship.extensionStatuses.defaultPlacement = placement;
258
+ config.components.extensionStatuses.defaultVisibility = placement === "off" ? "hide" : "show";
259
+ if (placement !== "off") {
260
+ if (config.components.footer.style === "hidden") {
261
+ config.components.extensionStatuses.hidden ??= {};
262
+ config.components.extensionStatuses.hidden.defaultPlacement = placement;
263
+ } else
264
+ config.components.footer.styles.starship.extensionStatuses.defaultPlacement = placement;
265
+ }
266
+ },
267
+ setExtensionStatusChoice(key: string, choice: "default" | ExtensionStatusPlacement) {
268
+ const owner = config.components.extensionStatuses;
269
+ let placements = config.components.footer.styles.starship.extensionStatuses.placements;
270
+ if (config.components.footer.style === "hidden") {
271
+ owner.hidden ??= {};
272
+ owner.hidden.placements ??= {};
273
+ placements = owner.hidden.placements;
274
+ }
275
+ if (choice === "default") {
276
+ delete owner.visibility[key];
277
+ delete placements[key];
278
+ } else {
279
+ Object.defineProperty(owner.visibility, key, {
280
+ value: choice === "off" ? "hide" : "show",
281
+ enumerable: true,
282
+ configurable: true,
283
+ writable: true,
284
+ });
285
+ if (choice !== "off")
286
+ Object.defineProperty(placements, key, {
287
+ value: choice,
288
+ enumerable: true,
289
+ configurable: true,
290
+ writable: true,
291
+ });
292
+ }
293
+ },
294
+ setHiddenExtensionStatusColorMode(key: string, colorMode: ExtensionStatusColorMode) {
295
+ config.components.extensionStatuses.hidden ??= {};
296
+ const hidden = config.components.extensionStatuses.hidden;
297
+ hidden.colorModes ??= {};
298
+ if (colorMode === "original") delete hidden.colorModes[key];
299
+ else
300
+ Object.defineProperty(hidden.colorModes, key, {
301
+ value: colorMode,
302
+ enumerable: true,
303
+ configurable: true,
304
+ writable: true,
305
+ });
306
+ },
307
+ setExtensionStatusColorMode(key: string, colorMode: ExtensionStatusColorMode) {
308
+ config.components.footer.styles.starship.extensionStatuses.colorModes[key] = colorMode;
236
309
  },
237
- setExtensionStatusPlacement() {},
238
- setExtensionStatusColorMode() {},
239
310
  requestRender() {
240
311
  calls.renders.shared += 1;
241
312
  },
@@ -288,6 +359,7 @@ function createHarness(
288
359
  };
289
360
  return {
290
361
  config,
362
+ deps,
291
363
  command: () => {
292
364
  if (!command) throw new Error("Command was not registered");
293
365
  return command;
@@ -309,12 +381,77 @@ afterEach(() => {
309
381
  vi.useRealTimers();
310
382
  });
311
383
 
384
+ describe("focused OMP skin settings", () => {
385
+ it("defaults to Editor and cycles only the three supported owners", async () => {
386
+ const h = createHarness(cloneConfig(), { skinOnly: true });
387
+ await h.command().handler("", h.ctx);
388
+ const component = h.component();
389
+ expect(component.render(160)[1]).toContain("[Editor] / User messages / Statusline");
390
+ component.handleInput("\t");
391
+ expect(component.render(160)[1]).toContain("Editor / [User messages] / Statusline");
392
+ component.handleInput("\t");
393
+ expect(component.render(160)[1]).toContain("Editor / User messages / [Statusline]");
394
+ component.handleInput("\t");
395
+ expect(component.render(160)[1]).toContain("[Editor] / User messages / Statusline");
396
+ component.handleInput("\x1b[Z");
397
+ expect(component.render(160)[1]).toContain("Editor / User messages / [Statusline]");
398
+ });
399
+
400
+ it("rejects unsupported pages and migration without changing saved owners", async () => {
401
+ const h = createHarness(cloneConfig(), { skinOnly: true });
402
+ const before = structuredClone(h.config);
403
+ for (const route of [
404
+ "appearance",
405
+ "thinking",
406
+ "thinking-steps",
407
+ "working-line",
408
+ "extensions",
409
+ "migrate",
410
+ ]) {
411
+ await h.command().handler(route, h.ctx);
412
+ expect(h.notifications.at(-1)).toContain("host-owned");
413
+ }
414
+ expect(h.config).toEqual(before);
415
+ expect(h.calls.thinkingSteps).toEqual([]);
416
+ expect(h.calls.workingLine).toEqual([]);
417
+ expect(h.calls.selectors).toEqual([]);
418
+ const completions = h
419
+ .command()
420
+ .getArgumentCompletions("")
421
+ ?.map(({ value }) => value);
422
+ for (const route of ["appearance", "thinking", "working-line", "extensions", "migrate"]) {
423
+ expect(completions).not.toContain(route);
424
+ }
425
+ expect(completions).toContain("statusline");
426
+ });
427
+
428
+ it("retains supported shared presets without saving unsupported owners", async () => {
429
+ const h = createHarness(cloneConfig(), { skinOnly: true });
430
+ const unsupported = structuredClone({
431
+ working: h.config.components.workingLine,
432
+ thinking: h.config.components.thinkingSteps,
433
+ selectors: h.config.components.selectorBorders,
434
+ });
435
+ await h.command().handler("preset rail", h.ctx);
436
+ expect(h.calls.presets).toEqual(["rail"]);
437
+ expect(h.config.components.editor.style).toBe("accent-rail");
438
+ expect(h.config.components.userMessages.style).toBe("compact");
439
+ expect(h.config.components.footer.style).toBe("starship");
440
+ expect({
441
+ working: h.config.components.workingLine,
442
+ thinking: h.config.components.thinkingSteps,
443
+ selectors: h.config.components.selectorBorders,
444
+ }).toEqual(unsupported);
445
+ });
446
+ });
447
+
312
448
  describe("component-oriented /zentui settings", () => {
313
- it("uses the exact nine-section order in wide and narrow navigation", async () => {
449
+ it("uses the exact seven-section order in wide and narrow navigation", async () => {
314
450
  const harness = createHarness();
315
451
  await harness.command().handler("", harness.ctx);
316
452
  const component = harness.component();
317
453
  const wide = component.render(200).join("\n");
454
+ for (const child of footerPageNames) expect(component.render(200)[1]).not.toContain(child);
318
455
  let previous = -1;
319
456
  for (const name of sectionNames) {
320
457
  const index = wide.indexOf(name);
@@ -324,7 +461,7 @@ describe("component-oriented /zentui settings", () => {
324
461
  for (const [index, name] of sectionNames.entries()) {
325
462
  const lines = component.render(40);
326
463
  expect(lines[1]).toContain(name);
327
- expect(lines[1]).toContain(`(${index + 1}/9)`);
464
+ expect(lines[1]).toContain(`(${index + 1}/7)`);
328
465
  expect(lines.every((line) => visibleWidth(line) <= 40)).toBe(true);
329
466
  component.handleInput("\t");
330
467
  }
@@ -343,6 +480,40 @@ describe("component-oriented /zentui settings", () => {
343
480
  expect(tokenRows).toContain("reconciles.");
344
481
  });
345
482
 
483
+ it("saves quota toggles independently, including dormant editor preferences", async () => {
484
+ const config = cloneConfig();
485
+ config.components.editor.enabled = false;
486
+ const harness = createHarness(config);
487
+ await harness.command().handler("", harness.ctx);
488
+ const component = harness.component();
489
+ goToSection(component, "Editor");
490
+ selectLabel(component, "Codex quota");
491
+ component.handleInput(" ");
492
+ expect(harness.calls.editor).toEqual([{ codexQuota: true }]);
493
+ expect(config.components.editor.enabled).toBe(false);
494
+ expect(config.components.footer.codexQuota).toBe(false);
495
+ for (let index = 0; index < 4; index++) component.handleInput("\t");
496
+ selectLabel(component, "Codex quota");
497
+ component.handleInput(" ");
498
+ expect(harness.calls.footer).toEqual([{ codexQuota: true }]);
499
+ expect(config.components.editor.codexQuota).toBe(true);
500
+ });
501
+
502
+ it("restores quota settings after a failed save", async () => {
503
+ const harness = createHarness(cloneConfig(), {
504
+ setEditorComponent() {
505
+ throw new Error("read-only quota");
506
+ },
507
+ });
508
+ await harness.command().handler("", harness.ctx);
509
+ const component = harness.component();
510
+ goToSection(component, "Editor");
511
+ selectLabel(component, "Codex quota");
512
+ component.handleInput(" ");
513
+ expect(row(component, "Codex quota")).toContain("disabled");
514
+ expect(harness.notifications).toContain("Could not update Zentui settings: read-only quota");
515
+ });
516
+
346
517
  it("uses exact component-owned row sets and ordering", async () => {
347
518
  const harness = createHarness();
348
519
  await harness.command().handler("", harness.ctx);
@@ -353,6 +524,9 @@ describe("component-oriented /zentui settings", () => {
353
524
  "Selector border style",
354
525
  "Selector border colors",
355
526
  "Icon mode",
527
+
528
+ "Color overrides",
529
+ "Migrate component selections",
356
530
  ]);
357
531
 
358
532
  goToSection(component, "Editor");
@@ -360,20 +534,31 @@ describe("component-oriented /zentui settings", () => {
360
534
  "Editor",
361
535
  "Editor style",
362
536
  "Editor colors",
537
+ "Codex quota",
363
538
  "Editor model label",
364
539
  "Editor border color",
365
540
  "Editor viewport indicators",
366
541
  "Completion menu",
542
+
543
+ "Color overrides",
544
+ "Individual custom value colors",
367
545
  ]);
368
546
 
369
547
  component.handleInput("\t");
370
- expectFocusOrder(component, ["User messages", "Message style", "Message colors"]);
548
+ expectFocusOrder(component, [
549
+ "User messages",
550
+ "Message style",
551
+ "Message colors",
552
+ "Color overrides",
553
+ ]);
371
554
  component.handleInput("\t");
372
555
  expectFocusOrder(component, ["Enabled", "Mode"]);
373
556
  component.handleInput("\t");
374
557
  expectFocusOrder(component, [
375
558
  "Enabled",
559
+ "Placement",
376
560
  "Turn summary",
561
+ "Turn summary format",
377
562
  "Spinner",
378
563
  "Spinner speed",
379
564
  "Animate spinner color",
@@ -384,13 +569,17 @@ describe("component-oriented /zentui settings", () => {
384
569
  "Tool",
385
570
  "Elapsed",
386
571
  "Thinking time",
572
+ "Token rate",
387
573
  "Tokens",
388
574
  "Message list",
575
+
576
+ "Color overrides",
389
577
  ]);
390
578
  component.handleInput("\t");
391
579
  expectFocusOrder(component, [
392
580
  "Footer style",
393
581
  "Footer colors",
582
+ "Codex quota",
394
583
  "Footer model label",
395
584
  "Responsive footer",
396
585
  "Compact footer rows",
@@ -398,8 +587,12 @@ describe("component-oriented /zentui settings", () => {
398
587
  "Separator",
399
588
  "Path display",
400
589
  "Path depth",
590
+ "Segments",
591
+ "Git",
592
+ "Color overrides",
593
+ "Individual custom value colors",
401
594
  ]);
402
- component.handleInput("\t");
595
+ openFooterPage(component, "Segments");
403
596
  expectFocusOrder(component, [
404
597
  "Current directory",
405
598
  "Session name",
@@ -414,7 +607,8 @@ describe("component-oriented /zentui settings", () => {
414
607
  "OS icon",
415
608
  "Package version",
416
609
  ]);
417
- component.handleInput("\t");
610
+ component.handleInput("\x1b");
611
+ openFooterPage(component, "Git");
418
612
  expectFocusOrder(component, [
419
613
  "Git branch",
420
614
  "Branch length",
@@ -427,12 +621,13 @@ describe("component-oriented /zentui settings", () => {
427
621
  "Hide zero metrics",
428
622
  "Ignore submodules",
429
623
  ]);
624
+ component.handleInput("\x1b");
430
625
  component.handleInput("\t");
431
- expectFocusOrder(component, ["Default placement", "No active statuses"]);
626
+ expectFocusOrder(component, ["Default placement", "No observed statuses"]);
432
627
  });
433
628
 
434
629
  it.each(["native", "hidden"] as const)(
435
- "shows only Footer style for %s while retaining Starship preconfiguration sections",
630
+ "shows Footer style and color preconfiguration for %s",
436
631
  async (style) => {
437
632
  const config = cloneConfig();
438
633
  config.components.footer.style = style;
@@ -440,26 +635,14 @@ describe("component-oriented /zentui settings", () => {
440
635
  await harness.command().handler("", harness.ctx);
441
636
  const component = harness.component();
442
637
  goToSection(component, "Footer");
443
- expectFocusOrder(component, ["Footer style"]);
444
- component.handleInput("\t");
445
- expectFocusOrder(component, [
446
- "Current directory",
447
- "Session name",
448
- "Runtime",
449
- "Model info",
450
- "Context usage",
451
- "Token counts",
452
- "Session cost",
453
- "Session duration",
454
- "Username@host",
455
- "Current time",
456
- "OS icon",
457
- "Package version",
458
- ]);
459
- component.handleInput("\t");
460
- expect(row(component, "Git branch")).toContain("enabled");
638
+ expectFocusOrder(component, ["Footer style", "Color overrides"]);
639
+
640
+ const before = structuredClone(config);
641
+ for (const page of footerPageNames)
642
+ expect(component.render(200).join("\n")).not.toContain(page);
461
643
  component.handleInput("\t");
462
- expect(row(component, "Default placement")).toContain("right");
644
+ expect(component.render(40)[1]).toContain("Extension statuses");
645
+ expect(config).toEqual(before);
463
646
  },
464
647
  );
465
648
 
@@ -496,7 +679,7 @@ describe("component-oriented /zentui settings", () => {
496
679
  component.handleInput(" ");
497
680
  expect(focusedRow(component)).toContain("> Footer style");
498
681
  expect(focusedRow(component)).toContain("Native");
499
- expectFocusOrder(component, ["Footer style"]);
682
+ expectFocusOrder(component, ["Footer style", "Color overrides"]);
500
683
  expect(harness.notifications).toEqual(["Could not update Zentui settings: read-only footer"]);
501
684
  });
502
685
 
@@ -513,6 +696,7 @@ describe("component-oriented /zentui settings", () => {
513
696
  "Editor",
514
697
  "Editor style",
515
698
  "Editor colors",
699
+ "Codex quota",
516
700
  "Editor model label",
517
701
  "Editor border color",
518
702
  "Editor viewport indicators",
@@ -522,10 +706,22 @@ describe("component-oriented /zentui settings", () => {
522
706
  "Session name",
523
707
  "Timer",
524
708
  "Cost",
709
+ "Cache hit rate",
525
710
  "Git",
711
+ "Separator",
712
+ "Custom value colors",
713
+ "Metadata templates",
714
+ "Custom variable aliases",
715
+ "Color overrides",
716
+ "Individual custom value colors",
526
717
  ]);
527
718
  component.handleInput("\t");
528
- expectFocusOrder(component, ["User messages", "Message style", "Message colors"]);
719
+ expectFocusOrder(component, [
720
+ "User messages",
721
+ "Message style",
722
+ "Message colors",
723
+ "Color overrides",
724
+ ]);
529
725
  });
530
726
 
531
727
  it("routes every minimalist, Git option, and default-placement action", async () => {
@@ -543,7 +739,9 @@ describe("component-oriented /zentui settings", () => {
543
739
  ["Session name", "disabled"],
544
740
  ["Timer", "disabled"],
545
741
  ["Cost", "disabled"],
742
+ ["Cache hit rate", "enabled"],
546
743
  ["Git", "disabled"],
744
+ ["Separator", "dot"],
547
745
  ] as const) {
548
746
  selectLabel(component, label);
549
747
  component.handleInput(" ");
@@ -557,10 +755,13 @@ describe("component-oriented /zentui settings", () => {
557
755
  { showSessionName: false },
558
756
  { showTimer: false },
559
757
  { showCost: false },
758
+ { showCacheHit: true },
560
759
  { showGit: false },
760
+ { separator: "dot" },
561
761
  ]);
562
762
 
563
- for (let index = 0; index < 6; index += 1) component.handleInput("\t");
763
+ for (let index = 0; index < 4; index += 1) component.handleInput("\t");
764
+ openFooterPage(component, "Git");
564
765
  for (const [label, value] of [
565
766
  ["Commit only on detached HEAD", "disabled"],
566
767
  ["Show exact-match tag", "disabled"],
@@ -575,13 +776,14 @@ describe("component-oriented /zentui settings", () => {
575
776
  expect(harness.calls.gitCommit).toEqual([{ onlyDetached: false }, { showTag: false }]);
576
777
  expect(harness.calls.gitMetrics).toEqual([{ onlyNonzero: false }, { ignoreSubmodules: true }]);
577
778
 
779
+ component.handleInput("\x1b");
578
780
  component.handleInput("\t");
579
781
  selectLabel(component, "Default placement");
580
782
  component.handleInput(" ");
581
783
  expect(focusedRow(component)).toContain("> Default placement");
582
- expect(focusedRow(component)).toContain("off");
784
+ expect(focusedRow(component)).toContain("Off");
583
785
  expect(harness.calls.extensionDefaultPlacement).toEqual(["off"]);
584
- expect(config.components.footer.styles.starship.extensionStatuses.defaultPlacement).toBe("off");
786
+ expect(config.components.extensionStatuses.defaultVisibility).toBe("hide");
585
787
  });
586
788
 
587
789
  it("restores editor-style focus by ID after dynamic rebuild", async () => {
@@ -635,27 +837,36 @@ describe("component-oriented /zentui settings", () => {
635
837
  expect(component.render(100).join("\n")).not.toContain("Completion menu");
636
838
  });
637
839
 
638
- it("shows and persists the Accent Rail surface control only for that style", async () => {
840
+ it("changes the rail background in OMP settings without changing another component or style", async () => {
639
841
  const current = cloneConfig();
640
842
  current.components.editor.style = "accent-rail";
641
- const harness = createHarness(current);
642
- await harness.command().handler("", harness.ctx);
843
+ const before = structuredClone(current);
844
+ const harness = createHarness(current, { skinOnly: true });
845
+ await harness.command().handler("editor", harness.ctx);
643
846
  const component = harness.component();
644
- goToSection(component, "Editor");
645
- selectLabel(component, "Accent Rail surface");
646
- expect(focusedRow(component)).toContain("filled");
847
+ const surfaceTheme = theme();
848
+ surfaceTheme.getBgAnsi = () => "\x1b[48;5;234m";
849
+ const render = () =>
850
+ renderAccentRailEditorFrame({
851
+ width: 30,
852
+ editorLines: ["draft"],
853
+ uiTheme: surfaceTheme,
854
+ config: current,
855
+ });
856
+ expect(render()[0]).toContain("\x1b[48;5;234m");
857
+ selectLabel(component, "Editor background");
647
858
  component.handleInput(" ");
648
- expect(focusedRow(component)).toContain("transparent");
649
- expect(harness.calls.accentRail).toEqual([{ transparent: true }]);
650
- expect(harness.calls.editor).toEqual([]);
651
- expect(current.components.editor.styles.minimalist).toEqual({
652
- ...defaultConfig.components.editor.styles.minimalist,
653
- contextGauge: false,
654
- });
655
-
656
- selectLabel(component, "Editor style");
859
+ expect(render()[0]).not.toContain("\x1b[48;5;234m");
860
+ expect(current.components.editor.styles["accent-rail"].transparent).toBe(true);
861
+ expect(current.components.editor.style).toBe("accent-rail");
862
+ expect(current.components.footer).toEqual(before.components.footer);
863
+ expect(current.components.userMessages).toEqual(before.components.userMessages);
864
+ expect(current.components.editor.styles.minimalist).toEqual(
865
+ before.components.editor.styles.minimalist,
866
+ );
657
867
  component.handleInput(" ");
658
- expect(component.render(80).join("\n")).not.toContain("Accent Rail surface");
868
+ expect(render()[0]).toContain("\x1b[48;5;234m");
869
+ expect(current.components.editor.styles["accent-rail"].transparent).toBe(false);
659
870
  });
660
871
 
661
872
  it("shows friendly message style labels and restores focus after rebuild", async () => {
@@ -803,14 +1014,15 @@ describe("component-oriented /zentui settings", () => {
803
1014
  component.handleInput("\t");
804
1015
  component.handleInput("\t");
805
1016
  component.handleInput("\t");
806
- component.handleInput("\t");
807
- component.handleInput("\t");
1017
+ openFooterPage(component, "Git");
808
1018
  selectLabel(component, "Ignore submodules");
809
1019
  component.handleInput(" ");
810
- component.handleInput("\x1b[Z");
1020
+ component.handleInput("\x1b");
1021
+ openFooterPage(component, "Segments");
811
1022
  selectLabel(component, "Model info");
812
1023
  component.handleInput(" ");
813
1024
  component.handleInput("\x1b");
1025
+ component.handleInput("\x1b");
814
1026
  expect(harness.doneCalls()).toBe(1);
815
1027
 
816
1028
  await harness.command().handler("", harness.ctx);
@@ -822,15 +1034,16 @@ describe("component-oriented /zentui settings", () => {
822
1034
  component.handleInput("\t");
823
1035
  component.handleInput("\t");
824
1036
  component.handleInput("\t");
825
- component.handleInput("\t");
826
- component.handleInput("\t");
1037
+ openFooterPage(component, "Git");
827
1038
  expect(row(component, "Ignore submodules")).toContain("enabled");
828
- component.handleInput("\x1b[Z");
1039
+ component.handleInput("\x1b");
1040
+ openFooterPage(component, "Segments");
829
1041
  expect(row(component, "Model info")).toContain("enabled");
830
1042
  expect(harness.calls.editor).toEqual([{ borderColorMode: "adaptive" }, { modelLabel: "name" }]);
831
1043
  expect(harness.calls.gitMetrics).toEqual([{ ignoreSubmodules: true }]);
832
1044
  expect(harness.calls.segments).toEqual([{ modelInfo: true }]);
833
1045
  component.handleInput("\x1b");
1046
+ component.handleInput("\x1b");
834
1047
  expect(harness.doneCalls()).toBe(2);
835
1048
  });
836
1049
 
@@ -855,7 +1068,7 @@ describe("component-oriented /zentui settings", () => {
855
1068
  component.handleInput("\t");
856
1069
  component.handleInput("\t");
857
1070
  component.handleInput("\t");
858
- component.handleInput("\t");
1071
+ openFooterPage(component, "Segments");
859
1072
  selectLabel(component, "Model info");
860
1073
  component.handleInput(" ");
861
1074
  expect(focusedRow(component)).toContain("> Model info");
@@ -1105,7 +1318,7 @@ describe("component-oriented /zentui settings", () => {
1105
1318
  });
1106
1319
  });
1107
1320
 
1108
- it("restores Thinking-step rows after persistence failure and exposes no direct route", async () => {
1321
+ it("restores Thinking-step rows after persistence failure and accepts its section route", async () => {
1109
1322
  const harness = createHarness(cloneConfig(), {
1110
1323
  setThinkingStepsComponent() {
1111
1324
  throw new Error("read-only thinking");
@@ -1119,23 +1332,68 @@ describe("component-oriented /zentui settings", () => {
1119
1332
  expect(focusedRow(component)).toContain("disabled");
1120
1333
  expect(harness.notifications).toContain("Could not update Zentui settings: read-only thinking");
1121
1334
  await harness.command().handler("thinking-steps", harness.ctx);
1122
- expect(harness.notifications.at(-1)).toMatch(/^Usage:/);
1335
+ expect(harness.component().render(40)[1]).toContain("Thinking");
1123
1336
  expect(
1124
1337
  harness
1125
1338
  .command()
1126
1339
  .getArgumentCompletions("")
1127
1340
  ?.map((item) => item.value)
1128
1341
  .join("\n"),
1129
- ).not.toMatch(/thinking.steps/i);
1342
+ ).toMatch(/thinking.steps/i);
1130
1343
  });
1131
1344
 
1345
+ it.each(["minimalist", "opencode", "opencode-copy-friendly"] as const)(
1346
+ "offers only Above/Border for %s without changing Editor",
1347
+ async (style) => {
1348
+ const config = cloneConfig();
1349
+ config.components.editor.style = style;
1350
+ config.components.editor.enabled = true;
1351
+ const editor = structuredClone(config.components.editor);
1352
+ const h = createHarness(config);
1353
+ await h.command().handler("working-line", h.ctx);
1354
+ const panel = h.component();
1355
+ selectLabel(panel, "Placement");
1356
+ expect(focusedRow(panel)).toMatch(/Above$/);
1357
+ panel.handleInput(" ");
1358
+ expect(focusedRow(panel)).toMatch(/Border$/);
1359
+ panel.handleInput(" ");
1360
+ expect(focusedRow(panel)).toMatch(/Above$/);
1361
+ expect(h.calls.workingLine).toEqual([{ placement: "border" }, { placement: "above" }]);
1362
+ expect(config.components.editor).toEqual(editor);
1363
+ expect(h.calls.editor).toEqual([]);
1364
+ },
1365
+ );
1366
+
1367
+ it.each(["accent-rail", "disabled"] as const)(
1368
+ "hides Placement for %s and guards stale selection without changing saved Border",
1369
+ async (mode) => {
1370
+ const config = cloneConfig();
1371
+ config.components.editor.enabled = true;
1372
+ config.components.editor.style = "minimalist";
1373
+ const h = createHarness(config);
1374
+ await h.command().handler("working-line", h.ctx);
1375
+ selectLabel(h.component(), "Placement");
1376
+ if (mode === "accent-rail") config.components.editor.style = "accent-rail";
1377
+ else config.components.editor.enabled = false;
1378
+ h.component().handleInput(" ");
1379
+ expect(h.calls.workingLine).toEqual([]);
1380
+ config.components.workingLine.placement = "border";
1381
+ h.component().handleInput("\x1b");
1382
+ await h.command().handler("working-line", h.ctx);
1383
+ expect(h.component().render(160).join("\n")).not.toContain("Placement");
1384
+ expect(config.components.workingLine.placement).toBe("border");
1385
+ },
1386
+ );
1387
+
1132
1388
  it("routes all Working-line rows independently", async () => {
1133
1389
  const harness = createHarness();
1134
1390
  await harness.command().handler("working-line", harness.ctx);
1135
1391
  const component = harness.component();
1136
1392
  expectFocusOrder(component, [
1137
1393
  "Enabled",
1394
+ "Placement",
1138
1395
  "Turn summary",
1396
+ "Turn summary format",
1139
1397
  "Spinner",
1140
1398
  "Spinner speed",
1141
1399
  "Animate spinner color",
@@ -1146,11 +1404,15 @@ describe("component-oriented /zentui settings", () => {
1146
1404
  "Tool",
1147
1405
  "Elapsed",
1148
1406
  "Thinking time",
1407
+ "Token rate",
1149
1408
  "Tokens",
1150
1409
  "Message list",
1410
+
1411
+ "Color overrides",
1151
1412
  ]);
1152
1413
  for (const [label, expected] of [
1153
1414
  ["Enabled", "enabled"],
1415
+ ["Placement", "Border"],
1154
1416
  ["Turn summary", "disabled"],
1155
1417
  ["Spinner", "ASCII Pinwheel"],
1156
1418
  ["Spinner speed", "Slow 160 ms"],
@@ -1170,6 +1432,7 @@ describe("component-oriented /zentui settings", () => {
1170
1432
  }
1171
1433
  expect(harness.calls.workingLine).toEqual([
1172
1434
  { enabled: true },
1435
+ { placement: "border" },
1173
1436
  { turnSummary: false },
1174
1437
  { spinner: "pinwheel" },
1175
1438
  { spinnerIntervalMs: 160 },
@@ -1183,7 +1446,8 @@ describe("component-oriented /zentui settings", () => {
1183
1446
  { segments: { thought: false } },
1184
1447
  { segments: { tokens: false } },
1185
1448
  ]);
1186
- expect(harness.calls.renders).toEqual({ shared: 0, local: 13 });
1449
+ expect(harness.calls.renders.shared).toBe(0);
1450
+ expect(harness.calls.renders.local).toBeGreaterThanOrEqual(14);
1187
1451
  });
1188
1452
 
1189
1453
  it("displays, previews, and stores all named spinner presets with canonical IDs", async () => {
@@ -1338,7 +1602,8 @@ describe("component-oriented /zentui settings", () => {
1338
1602
  await harness.command().handler("", harness.ctx);
1339
1603
  selectLabel(harness.component(), "Selector borders");
1340
1604
  harness.component().handleInput(" ");
1341
- expect(harness.calls.renders).toEqual({ shared: 1, local: 1 });
1605
+ expect(harness.calls.renders.shared).toBe(1);
1606
+ expect(harness.calls.renders.local).toBeGreaterThanOrEqual(1);
1342
1607
  });
1343
1608
 
1344
1609
  it.each([
@@ -1354,9 +1619,7 @@ describe("component-oriented /zentui settings", () => {
1354
1619
  await harness.command().handler("", harness.ctx);
1355
1620
  const component = harness.component();
1356
1621
  goToSection(component, section);
1357
- const zeroWidthRows = component.render(0);
1358
- const oneCellRows = component.render(1);
1359
- expect(zeroWidthRows).toHaveLength(oneCellRows.length);
1622
+ expect(component.render(0)).toEqual([]);
1360
1623
  for (const width of [0, 1, 4]) {
1361
1624
  const rows = component.render(width);
1362
1625
  expect(rows.every((line) => visibleWidth(line) <= width)).toBe(true);
@@ -1366,14 +1629,14 @@ describe("component-oriented /zentui settings", () => {
1366
1629
  const rows = component.render(width);
1367
1630
  expect(rows.every((line) => visibleWidth(line) <= width)).toBe(true);
1368
1631
  expectStackedPreview(rows, previewText);
1369
- expect(rows.some((line) => line.includes("> "))).toBe(true);
1632
+ expect(rows.some((line) => line.startsWith("> "))).toBe(true);
1370
1633
  }
1371
1634
  component.handleInput("\x1b");
1372
1635
  expect(vi.getTimerCount()).toBe(0);
1373
1636
  },
1374
1637
  );
1375
1638
 
1376
- it.each(["Appearance", "Footer", "Segments", "Git", "Extensions"] as const)(
1639
+ it.each(["Appearance", "Footer", "Segments", "Git", "Extension statuses"] as const)(
1377
1640
  "does not add preview spacer rows in %s",
1378
1641
  async (section) => {
1379
1642
  const harness = createHarness();
@@ -1448,14 +1711,26 @@ describe("component-oriented /zentui settings", () => {
1448
1711
  ]);
1449
1712
  expect(vi.getTimerCount()).toBe(0);
1450
1713
  component.handleInput("\t");
1451
- expect(component.render(100).join("\n")).toContain("Thinking");
1714
+ expectStackedPreview(component.render(100), "Verify compatibility");
1452
1715
  component.handleInput("\t");
1453
1716
  const workingRows = component.render(100);
1454
1717
  expectStackedPreview(workingRows, "Sautéing…");
1455
1718
  component.handleInput("\t");
1456
- for (const section of ["Footer", "Segments", "Git", "Extensions"] as const) {
1719
+ expect(harness.config.components.footer.style).toBe("starship");
1720
+ for (const width of [40, 60, 80, 120, 160]) {
1721
+ const rows = component.render(width);
1722
+ expect(rows[3]).toContain("> Footer style");
1723
+ expect(rows.join("\n")).not.toMatch(/samples?|synthetic|sonnet-long-context-preview/i);
1724
+ }
1725
+ expect(row(component, "Footer colors")).toContain("theme");
1726
+ component.handleInput(" ");
1727
+ expect(harness.calls.footer).toEqual([{ colorSource: "terminal" }]);
1728
+ for (const label of ["Footer model label", "Responsive footer", "Color overrides"])
1729
+ expect(row(component, label)).toContain(`> ${label}`);
1730
+ for (const section of footerPageNames) {
1731
+ openFooterPage(component, section);
1457
1732
  expect(leadingEmptyRowCount(component.render(100)), section).toBe(0);
1458
- if (section !== "Extensions") component.handleInput("\t");
1733
+ component.handleInput("\x1b");
1459
1734
  }
1460
1735
  expect(vi.getTimerCount()).toBe(0);
1461
1736
  });
@@ -1865,3 +2140,976 @@ describe("preset commands and Appearance selection", () => {
1865
2140
  },
1866
2141
  );
1867
2142
  });
2143
+
2144
+ describe("Footer layout authority disclosure", () => {
2145
+ it("explains built-in segment toggles versus independent wide and compact templates", async () => {
2146
+ const cfg = cloneConfig();
2147
+ const starship = cfg.components.footer.styles.starship;
2148
+ starship.segments.cwd = false;
2149
+ starship.segments.cost = true;
2150
+ starship.format = "$cwd";
2151
+ const templates = [starship.format, starship.compactFormat];
2152
+ const harness = createHarness(cfg);
2153
+ await harness.command().handler("", harness.ctx);
2154
+ const component = harness.component();
2155
+ goToSection(component, "Footer");
2156
+ selectLabel(component, "Responsive footer");
2157
+ expect(component.render(200).join("\n")).toContain("Reflow the wide layout");
2158
+ expect(component.render(200).join("\n")).toContain("independently of segment toggles");
2159
+ openFooterPage(component, "Segments");
2160
+ for (const label of ["Current directory", "Session cost"]) {
2161
+ selectLabel(component, label);
2162
+ const help = component.render(200).join("\n");
2163
+ expect(help).toContain("Built-in layout:");
2164
+ expect(help).toContain(
2165
+ "Explicit wide format and compactFormat templates choose their own segments",
2166
+ );
2167
+ component.handleInput(" ");
2168
+ }
2169
+ expect([starship.format, starship.compactFormat]).toEqual(templates);
2170
+ expect(harness.calls.segments).toEqual([{ cwd: true }, { cost: false }]);
2171
+ component.handleInput("\x1b");
2172
+ openFooterPage(component, "Git");
2173
+ selectLabel(component, "Git counts");
2174
+ expect(component.render(200).join("\n")).toContain(
2175
+ "built-in segments and template git-status variables",
2176
+ );
2177
+ });
2178
+
2179
+ it("clarifies that clearing format leaves compactFormat unchanged", async () => {
2180
+ const harness = createHarness();
2181
+ await harness.command().handler("format clear", harness.ctx);
2182
+ expect(harness.notifications).toContain(
2183
+ "Footer wide format cleared (using built-in segments; compactFormat unchanged)",
2184
+ );
2185
+ });
2186
+ });
2187
+
2188
+ describe("component independence settings actions", () => {
2189
+ it.each([
2190
+ ["Appearance", "selectorBorders", "border"],
2191
+ ["Editor", "editor", "accent"],
2192
+ ["User messages", "userMessages", "border"],
2193
+ ["Working line", "workingLine", "high"],
2194
+ ["Footer", "footer", "cwd"],
2195
+ ] as const)(
2196
+ "edits %s colors outside the disposed panel and restores focus",
2197
+ async (section, owner, role) => {
2198
+ let opens = 0;
2199
+ let disposed = false;
2200
+ const save = vi.fn();
2201
+ const select = vi
2202
+ .fn()
2203
+ .mockResolvedValueOnce(role)
2204
+ .mockResolvedValueOnce("Edit override")
2205
+ .mockResolvedValue(undefined);
2206
+ const harness = createHarness(
2207
+ cloneConfig(),
2208
+ { setComponentColor: save },
2209
+ {
2210
+ select,
2211
+ async editor() {
2212
+ expect(disposed).toBe(true);
2213
+ return "";
2214
+ },
2215
+ async custom(factory: (...args: unknown[]) => unknown) {
2216
+ let outcome: unknown;
2217
+ const component = factory({ requestRender() {} }, theme(), {}, (value: unknown) => {
2218
+ outcome = value;
2219
+ }) as Component & { dispose(): void };
2220
+ if (opens++ === 0) {
2221
+ goToSection(component, section);
2222
+ selectLabel(component, "Color overrides");
2223
+ component.handleInput(" ");
2224
+ } else {
2225
+ expect(focusedRow(component)).toContain("Color overrides");
2226
+ component.handleInput("\x1b");
2227
+ }
2228
+ component.dispose();
2229
+ disposed = true;
2230
+ return outcome;
2231
+ },
2232
+ },
2233
+ );
2234
+ await harness.command().handler("", harness.ctx);
2235
+ expect(opens).toBe(2);
2236
+ expect(save).toHaveBeenCalledExactlyOnceWith(owner, role, "", harness.ctx);
2237
+ },
2238
+ );
2239
+ it.each([true, false])(
2240
+ "confirms migration=%s from Appearance and reopens its action",
2241
+ async (confirmed) => {
2242
+ let opens = 0;
2243
+ const migrate = vi.fn();
2244
+ const confirm = vi.fn(async () => confirmed);
2245
+ const harness = createHarness(
2246
+ cloneConfig(),
2247
+ { migrateSelections: migrate },
2248
+ {
2249
+ confirm,
2250
+ async custom(factory: (...args: unknown[]) => unknown) {
2251
+ let outcome: unknown;
2252
+ const component = factory({ requestRender() {} }, theme(), {}, (value: unknown) => {
2253
+ outcome = value;
2254
+ }) as Component;
2255
+ if (opens++ === 0) {
2256
+ selectLabel(component, "Migrate component selections");
2257
+ component.handleInput(" ");
2258
+ } else {
2259
+ expect(focusedRow(component)).toContain("Migrate component selections");
2260
+ component.handleInput("\x1b");
2261
+ }
2262
+ return outcome;
2263
+ },
2264
+ },
2265
+ );
2266
+ await harness.command().handler("", harness.ctx);
2267
+ expect(confirm).toHaveBeenCalledOnce();
2268
+ expect(migrate).toHaveBeenCalledTimes(confirmed ? 1 : 0);
2269
+ expect(opens).toBe(2);
2270
+ },
2271
+ );
2272
+ it("routes /zentui migrate through confirmation and never reopens on stale confirmation", async () => {
2273
+ const migrate = vi.fn();
2274
+ const confirm = vi.fn(async () => true);
2275
+ const h = createHarness(cloneConfig(), { migrateSelections: migrate }, { confirm });
2276
+ await h.command().handler("migrate", h.ctx);
2277
+ expect(migrate).toHaveBeenCalledOnce();
2278
+ expect(h.command().getArgumentCompletions("mig")).toEqual([
2279
+ { value: "migrate", label: "migrate" },
2280
+ ]);
2281
+ confirm.mockImplementationOnce(async () => {
2282
+ h.sessionLifecycle.shutdown();
2283
+ h.sessionLifecycle.start();
2284
+ return true;
2285
+ });
2286
+ await h.command().handler("migrate", h.ctx);
2287
+ expect(migrate).toHaveBeenCalledOnce();
2288
+ });
2289
+ });
2290
+
2291
+ describe("settings clarity and navigation", () => {
2292
+ it("describes Working-line tiers and excludes template separators from the Separator choice", async () => {
2293
+ vi.useFakeTimers();
2294
+ const h = createHarness();
2295
+ await h.command().handler("working-line", h.ctx);
2296
+ selectLabel(h.component(), "Color overrides");
2297
+ const colors = h.component().render(200).join(" ").replace(/\s+/g, " ");
2298
+ expect(colors).toContain("Static Working line uses mid with optional Token rate override");
2299
+ expect(colors).toContain("Classic/KITT animate every segment; Turn summaries use high.");
2300
+ expect(colors).not.toContain("uses high only");
2301
+ await h.command().handler("footer", h.ctx);
2302
+ selectLabel(h.component(), "Separator");
2303
+ const help = h.component().render(200).join(" ").replace(/\s+/g, " ");
2304
+ expect(help).toContain("built-in/layout separators");
2305
+ expect(help).toContain("extension-status joins");
2306
+ expect(help).toContain("width can affect when the layout switches to compact");
2307
+ expect(help).toContain("Does not change $sep (fixed pipe) or literal template separators");
2308
+ h.sessionLifecycle.shutdown();
2309
+ });
2310
+
2311
+ it("activates Confirm semantically when the actual global manager binds Space to navigation", async () => {
2312
+ const previous = getKeybindings();
2313
+ const manager = new KeybindingsManager(TUI_KEYBINDINGS, { "tui.select.down": "space" });
2314
+ setKeybindings(manager);
2315
+ try {
2316
+ let panel: Component | undefined;
2317
+ const h = createHarness(
2318
+ cloneConfig(),
2319
+ {},
2320
+ {
2321
+ custom: async (factory: (...args: unknown[]) => Component) => {
2322
+ panel = factory({ requestRender() {} }, theme(), manager, () => {});
2323
+ },
2324
+ },
2325
+ );
2326
+ await h.command().handler("appearance", h.ctx);
2327
+ if (!panel) throw new Error("No panel");
2328
+ const help = panel.render(200).join("\n");
2329
+ expect(help).toContain("up/space Navigate");
2330
+ expect(help).toContain("enter Change");
2331
+ expect(help).not.toContain("/Space Change");
2332
+ panel.handleInput(" ");
2333
+ expect(focusedRow(panel)).toContain("Selector borders");
2334
+ panel.handleInput("\r");
2335
+ expect(h.calls.selectors).toEqual([{ enabled: false }]);
2336
+ expect(focusedRow(panel)).toContain("Selector borders");
2337
+ panel.handleInput("\r");
2338
+ expect(h.calls.selectors).toEqual([{ enabled: false }, { enabled: true }]);
2339
+ panel.handleInput(" ");
2340
+ expect(focusedRow(panel)).toContain("Selector border style");
2341
+ panel.handleInput("\r"); // Informational, not actionable.
2342
+ expect(h.calls.selectors).toHaveLength(2);
2343
+ expect(getKeybindings()).toBe(manager);
2344
+ expect(manager.getUserBindings()).toEqual({ "tui.select.down": "space" });
2345
+ } finally {
2346
+ setKeybindings(previous);
2347
+ }
2348
+ });
2349
+
2350
+ it.each(["Edit override", "Reset / inherit"])(
2351
+ "opens color dialogs with Confirm under global Space navigation and preserves %s",
2352
+ async (action) => {
2353
+ const previous = getKeybindings();
2354
+ const manager = new KeybindingsManager(TUI_KEYBINDINGS, { "tui.select.down": "space" });
2355
+ setKeybindings(manager);
2356
+ try {
2357
+ let opens = 0;
2358
+ const save = vi.fn();
2359
+ const h = createHarness(
2360
+ cloneConfig(),
2361
+ { setComponentColor: save },
2362
+ {
2363
+ select: vi.fn().mockResolvedValueOnce("border").mockResolvedValueOnce(action),
2364
+ editor: vi.fn().mockResolvedValue(""),
2365
+ custom: async (factory: (...args: unknown[]) => Component) => {
2366
+ let outcome: unknown;
2367
+ const panel = factory({ requestRender() {} }, theme(), manager, (value: unknown) => {
2368
+ outcome = value;
2369
+ });
2370
+ if (opens++ === 0) {
2371
+ for (let i = 0; i < 5; i++) panel.handleInput(" ");
2372
+ expect(focusedRow(panel)).toContain("Color overrides");
2373
+ panel.handleInput("\r");
2374
+ } else {
2375
+ expect(focusedRow(panel)).toContain("Color overrides");
2376
+ panel.handleInput("\x1b");
2377
+ }
2378
+ return outcome;
2379
+ },
2380
+ },
2381
+ );
2382
+ await h.command().handler("appearance", h.ctx);
2383
+ expect(opens).toBe(2);
2384
+ expect(save).toHaveBeenCalledExactlyOnceWith(
2385
+ "selectorBorders",
2386
+ "border",
2387
+ action === "Edit override" ? "" : undefined,
2388
+ h.ctx,
2389
+ );
2390
+ } finally {
2391
+ setKeybindings(previous);
2392
+ }
2393
+ },
2394
+ );
2395
+
2396
+ it.each([
2397
+ ["appearance", "Appearance"],
2398
+ ["editor", "Editor"],
2399
+ ["messages", "User messages"],
2400
+ ["user-messages", "User messages"],
2401
+ ["thinking", "Thinking"],
2402
+ ["thinking-steps", "Thinking"],
2403
+ ["working-line", "Working line"],
2404
+ ["footer", "Footer"],
2405
+ ["statusline", "Footer"],
2406
+ ["status", "Footer"],
2407
+ ["status-line", "Footer"],
2408
+ ["segments", "Segments"],
2409
+ ["git", "Git"],
2410
+ ["extensions", "Extension statuses"],
2411
+ ])("routes and completes %s without changing selections", async (route, label) => {
2412
+ vi.useFakeTimers();
2413
+ const h = createHarness();
2414
+ const before = structuredClone(h.config);
2415
+ await h.command().handler(route, h.ctx);
2416
+ expect(h.component().render(40)[1]).toContain(label);
2417
+ expect(
2418
+ h
2419
+ .command()
2420
+ .getArgumentCompletions(route)
2421
+ ?.map((item) => item.value),
2422
+ ).toContain(route);
2423
+ expect(h.config).toEqual(before);
2424
+ h.sessionLifecycle.shutdown();
2425
+ });
2426
+ it("marks dormant choices, explains icons, and makes selector style informational", async () => {
2427
+ const config = cloneConfig();
2428
+ config.components.editor.style = "accent-rail";
2429
+ config.components.footer.style = "hidden";
2430
+ const h = createHarness(config);
2431
+ await h.command().handler("appearance", h.ctx);
2432
+ selectLabel(h.component(), "Selector border style");
2433
+ h.component().handleInput(" ");
2434
+ expect(h.calls.selectors).toEqual([]);
2435
+ expect(h.component().render(160).join("\n")).toContain("Informational");
2436
+ selectLabel(h.component(), "Icon mode");
2437
+ const icons = h.component().render(160).join("\n").replace(/\s+/g, " ");
2438
+ expect(icons).toContain("TERM_PROGRAM=iTerm.app|WezTerm|ghostty");
2439
+ expect(icons).toContain("nonempty KITTY_WINDOW_ID or ALACRITTY_SOCKET");
2440
+ expect(icons).toContain("exact ZENTUI_NERD_FONTS=1|0");
2441
+ expect(icons).toContain("otherwise ASCII");
2442
+ expect(icons).toContain("cannot detect whether a Nerd Font is installed/configured");
2443
+ await h.command().handler("editor", h.ctx);
2444
+ selectLabel(h.component(), "Editor model label");
2445
+ expect(h.component().render(160).join("\n")).toContain("Saved for other editor styles");
2446
+ await h.command().handler("git", h.ctx);
2447
+ expect(h.component().render(40)[1]).toContain("Footer");
2448
+ expect(h.notifications).toContain(
2449
+ "Footer > Git requires Starship. Current Footer is Hidden; saved settings are unchanged.",
2450
+ );
2451
+ await h.command().handler("footer", h.ctx);
2452
+ expect(h.component().render(160).join("\n")).toContain(
2453
+ "Hidden keeps only allowed extension statuses",
2454
+ );
2455
+ config.components.footer.style = "native";
2456
+ await h.command().handler("footer", h.ctx);
2457
+ expect(h.component().render(160).join("\n")).toContain("predecessor");
2458
+ });
2459
+ it.each([8, 12, 18, 24])(
2460
+ "keeps selection, core help and close reachable at height %i",
2461
+ async (height) => {
2462
+ let component: Component | undefined;
2463
+ const h = createHarness(
2464
+ cloneConfig(),
2465
+ {},
2466
+ {
2467
+ custom: async (factory: (...args: unknown[]) => Component) => {
2468
+ component = factory(
2469
+ { terminal: { rows: height }, requestRender() {} },
2470
+ theme(),
2471
+ {},
2472
+ () => {},
2473
+ );
2474
+ },
2475
+ },
2476
+ );
2477
+ await h.command().handler("footer", h.ctx);
2478
+ if (!component) throw new Error("No panel");
2479
+ for (let i = 0; i < 12; i++) {
2480
+ const rows = component.render(40);
2481
+ expect(rows.join("\n")).not.toMatch(/samples?|synthetic/i);
2482
+ expect(rows.length).toBeLessThanOrEqual(height);
2483
+ expect(rows.every((row) => visibleWidth(row) <= 40)).toBe(true);
2484
+ const text = rows.join("\n");
2485
+ expect(text).toContain("Change");
2486
+ expect(text).toContain("Sections");
2487
+ expect(text).toContain("Close");
2488
+ expect(text).toContain("> ");
2489
+ component.handleInput("\x1b[B");
2490
+ }
2491
+ },
2492
+ );
2493
+ it("uses the injected remapped selection keys without changing global keybindings", async () => {
2494
+ let component: Component | undefined;
2495
+ let closed = 0;
2496
+ const bindings: Record<string, string[]> = {
2497
+ "tui.select.up": ["k"],
2498
+ "tui.select.down": ["j"],
2499
+ "tui.select.confirm": ["x"],
2500
+ "tui.select.cancel": ["q"],
2501
+ };
2502
+ const h = createHarness(
2503
+ cloneConfig(),
2504
+ {},
2505
+ {
2506
+ custom: async (factory: (...args: unknown[]) => Component) => {
2507
+ component = factory(
2508
+ { requestRender() {} },
2509
+ theme(),
2510
+ { getKeys: (id: string) => bindings[id] ?? [] },
2511
+ () => {
2512
+ closed++;
2513
+ },
2514
+ );
2515
+ },
2516
+ },
2517
+ );
2518
+ await h.command().handler("appearance", h.ctx);
2519
+ if (!component) throw new Error("No panel");
2520
+ component.handleInput("j");
2521
+ expect(focusedRow(component)).toContain("Selector borders");
2522
+ component.handleInput("x");
2523
+ expect(h.calls.selectors).toEqual([{ enabled: false }]);
2524
+ const narrow = component.render(32).join("\n");
2525
+ expect(narrow).toContain("x Change");
2526
+ expect(narrow).toContain("Tab Sections");
2527
+ expect(narrow).toContain("q Close");
2528
+ expect(narrow).not.toContain("Enter/Space");
2529
+ component.handleInput("k");
2530
+ expect(focusedRow(component)).toContain("Preset");
2531
+ component.handleInput("\t");
2532
+ expect(component.render(40)[1]).toContain("Editor");
2533
+ component.handleInput("\x1b[Z");
2534
+ expect(component.render(40)[1]).toContain("Appearance");
2535
+ component.handleInput("q");
2536
+ expect(closed).toBe(1);
2537
+ });
2538
+ });
2539
+
2540
+ describe("settings input lifecycle continuations", () => {
2541
+ const cases = ["Spinner speed", "Text motion speed", "Message list"].flatMap((label) =>
2542
+ ["save", "cancel", "error", "stale", "restarted", "stale-error"].map((result) => ({
2543
+ label,
2544
+ result,
2545
+ })),
2546
+ );
2547
+ it.each(cases)(
2548
+ "guards $label after $result and preserves the editor draft",
2549
+ async ({ label, result }) => {
2550
+ vi.useFakeTimers();
2551
+ const originalDraft = "expanded paste\n".repeat(30);
2552
+ let draft = originalDraft;
2553
+ let opened = 0;
2554
+ let inputs = 0;
2555
+ const enterInput = async () => {
2556
+ inputs++;
2557
+ // Model Pi's snapshot/restoration around a blocking input, not host scheduling.
2558
+ const saved = draft;
2559
+ draft = "temporary dialog";
2560
+ await Promise.resolve();
2561
+ draft = saved;
2562
+ if (result === "stale" || result === "restarted" || result === "stale-error")
2563
+ h.sessionLifecycle.shutdown();
2564
+ if (result === "restarted") h.sessionLifecycle.start();
2565
+ if (result === "error" || result === "stale-error") throw new Error("dialog failed");
2566
+ return result === "cancel" ? undefined : label === "Message list" ? "One\nTwo" : "123";
2567
+ };
2568
+ const h = createHarness(
2569
+ cloneConfig(),
2570
+ {},
2571
+ {
2572
+ getEditorText: () => draft,
2573
+ setEditorText: (value: string) => {
2574
+ draft = value;
2575
+ },
2576
+ input: enterInput,
2577
+ editor: enterInput,
2578
+ custom: async (factory: (...args: unknown[]) => Component) => {
2579
+ const snapshot = draft;
2580
+ let outcome: unknown;
2581
+ const component = factory({ requestRender() {} }, theme(), {}, (value: unknown) => {
2582
+ outcome = value;
2583
+ });
2584
+ if (opened++ === 0) {
2585
+ selectLabel(component, label);
2586
+ if (label === "Message list") component.handleInput(" ");
2587
+ else component.handleInput(" ");
2588
+ } else component.handleInput("\x1b");
2589
+ draft = snapshot;
2590
+ return outcome;
2591
+ },
2592
+ },
2593
+ );
2594
+ // Custom is reached from the slow preset without changing any speed first.
2595
+ if (label === "Spinner speed") h.config.components.workingLine.spinnerIntervalMs = 160;
2596
+ if (label === "Text motion speed") h.config.components.workingLine.textIntervalMs = 100;
2597
+ await h.command().handler("working-line", h.ctx);
2598
+ expect(inputs).toBe(1);
2599
+ expect(draft).toBe(originalDraft);
2600
+ const stale = ["stale", "restarted", "stale-error"].includes(result);
2601
+ expect(opened).toBe(stale ? 1 : 2);
2602
+ if (result === "save") expect(h.calls.workingLine).toHaveLength(1);
2603
+ else expect(h.calls.workingLine).toEqual([]);
2604
+ if (stale) expect(h.notifications).toEqual([]);
2605
+ if (result === "error")
2606
+ expect(h.notificationEvents).toEqual([
2607
+ { message: expect.stringContaining("dialog failed"), severity: "error" },
2608
+ ]);
2609
+ h.sessionLifecycle.shutdown();
2610
+ expect(vi.getTimerCount()).toBe(0);
2611
+ },
2612
+ );
2613
+ it.each([false, true])("contains panel rejection (stale=%s)", async (stale) => {
2614
+ const h = createHarness(
2615
+ cloneConfig(),
2616
+ {},
2617
+ {
2618
+ custom: async () => {
2619
+ if (stale) h.sessionLifecycle.shutdown();
2620
+ throw new Error("panel unavailable");
2621
+ },
2622
+ },
2623
+ );
2624
+ await h.command().handler("footer", h.ctx);
2625
+ if (stale) expect(h.notifications).toEqual([]);
2626
+ else
2627
+ expect(h.notificationEvents).toEqual([
2628
+ { message: expect.stringContaining("panel unavailable"), severity: "error" },
2629
+ ]);
2630
+ });
2631
+ });
2632
+
2633
+ describe("nested Starship Footer settings navigation", () => {
2634
+ const pages = [
2635
+ ["segments", "Segments", "Current directory"],
2636
+ ["git", "Git", "Git branch"],
2637
+ ] as const;
2638
+
2639
+ it.each(pages)(
2640
+ "opens %s and restores its Footer entry without saving or replacing the editor",
2641
+ async (route, label, firstRow) => {
2642
+ const draft = "expanded pasted draft\n".repeat(30);
2643
+ let text = draft;
2644
+ const replaceEditor = vi.fn();
2645
+ const h = createHarness(
2646
+ cloneConfig(),
2647
+ {},
2648
+ {
2649
+ getEditorText: () => text,
2650
+ setEditorText: (value: string) => {
2651
+ text = value;
2652
+ },
2653
+ setEditorComponent: replaceEditor,
2654
+ },
2655
+ );
2656
+ const effects = Object.keys(h.deps)
2657
+ .filter(
2658
+ (key) =>
2659
+ /^(set|apply|reconcile|migrate|requestRender)/.test(key) &&
2660
+ typeof h.deps[key as keyof typeof h.deps] === "function",
2661
+ )
2662
+ .map((key) => vi.spyOn(h.deps, key as "requestRender"));
2663
+ const before = structuredClone(h.config);
2664
+ await h.command().handler("footer", h.ctx);
2665
+ const panel = h.component();
2666
+ expect(row(panel, label)).toContain("->");
2667
+ panel.handleInput("\r");
2668
+ expect(panel.render(40)[1]).toContain(`Footer > ${label}`);
2669
+ expect(focusedRow(panel)).toContain(`> ${firstRow}`);
2670
+ expect(panel.render(40).join("\n")).toContain("escape Back");
2671
+ panel.handleInput("\x1b");
2672
+ expect(focusedRow(panel)).toContain(`> ${label}`);
2673
+ expect(h.doneCalls()).toBe(0);
2674
+ panel.handleInput("\r");
2675
+ panel.handleInput("\t");
2676
+ expect(panel.render(40)[1]).toContain("Extension statuses");
2677
+ panel.handleInput("\x1b[Z");
2678
+ expect(panel.render(40)[1]).toContain("Footer");
2679
+ panel.handleInput("\x1b");
2680
+ expect(h.doneCalls()).toBe(1);
2681
+ await h.command().handler(route, h.ctx);
2682
+ expect(h.component().render(40)[1]).toContain(`Footer > ${label}`);
2683
+ h.component().handleInput("\x1b[Z");
2684
+ expect(h.component().render(40)[1]).toContain("Working line");
2685
+ h.sessionLifecycle.shutdown();
2686
+ expect(h.config).toEqual(before);
2687
+ for (const effect of effects) expect(effect).not.toHaveBeenCalled();
2688
+ expect(replaceEditor).not.toHaveBeenCalled();
2689
+ expect(text).toBe(draft);
2690
+ expect(h.command().getArgumentCompletions(route)).toContainEqual({
2691
+ value: route,
2692
+ label: `${route} — Footer > ${label}`,
2693
+ });
2694
+ },
2695
+ );
2696
+
2697
+ it.each(["native", "hidden"] as const)(
2698
+ "redirects every legacy child shortcut under %s without exposing controls or changing preferences",
2699
+ async (style) => {
2700
+ const config = cloneConfig();
2701
+ config.components.footer.style = style;
2702
+ config.components.footer.styles.starship.gitBranch.maxLength = 37;
2703
+ config.components.footer.styles.starship.segments.cwd = false;
2704
+ const before = structuredClone(config);
2705
+ const h = createHarness(config);
2706
+ for (const [route, label, firstRow] of pages) {
2707
+ await h.command().handler(route, h.ctx);
2708
+ const panel = h.component();
2709
+ expect(panel.render(40)[1]).toContain("[Footer] (6/7)");
2710
+ expectFocusOrder(panel, ["Footer style", "Color overrides"]);
2711
+ expect(panel.render(200).join("\n")).not.toContain(firstRow);
2712
+ expect(h.notifications.at(-1)).toBe(
2713
+ `Footer > ${label} requires Starship. Current Footer is ${style === "native" ? "Native" : "Hidden"}; saved settings are unchanged.`,
2714
+ );
2715
+ panel.handleInput("\x1b");
2716
+ }
2717
+ expect(h.config).toEqual(before);
2718
+ expect(h.calls.footer).toEqual([]);
2719
+ expect(h.calls.renders.shared).toBe(0);
2720
+ },
2721
+ );
2722
+
2723
+ it.each([8, 12, 18, 24])(
2724
+ "keeps children, Back and Sections usable at 40 columns and height %i with remapped keys and global Space navigation",
2725
+ async (height) => {
2726
+ const previous = getKeybindings();
2727
+ const global = new KeybindingsManager(TUI_KEYBINDINGS, { "tui.select.down": "space" });
2728
+ setKeybindings(global);
2729
+ try {
2730
+ const down = height === 8 ? " " : "j";
2731
+ const bindings: Record<string, string[]> = {
2732
+ "tui.select.up": ["k"],
2733
+ "tui.select.down": [height === 8 ? "space" : "j"],
2734
+ "tui.select.confirm": ["x"],
2735
+ "tui.select.cancel": ["q"],
2736
+ };
2737
+ let panel: Component | undefined;
2738
+ let closed = 0;
2739
+ const h = createHarness(
2740
+ cloneConfig(),
2741
+ {},
2742
+ {
2743
+ custom: async (factory: (...args: unknown[]) => Component) => {
2744
+ panel = factory(
2745
+ { terminal: { rows: height }, requestRender() {} },
2746
+ theme(),
2747
+ { getKeys: (id: string) => bindings[id] ?? [] },
2748
+ () => {
2749
+ closed++;
2750
+ },
2751
+ );
2752
+ },
2753
+ },
2754
+ );
2755
+ const before = structuredClone(h.config);
2756
+ await h.command().handler("footer", h.ctx);
2757
+ if (!panel) throw new Error("No panel");
2758
+ for (const [, label, firstRow] of pages) {
2759
+ for (
2760
+ let i = 0;
2761
+ i < 20 && !panel.render(40).some((line) => line.startsWith(`> ${label}`));
2762
+ i++
2763
+ )
2764
+ panel.handleInput(down);
2765
+ expect(panel.render(40).join("\n")).toContain(`> ${label}`);
2766
+ panel.handleInput("x");
2767
+ expect(focusedRow(panel)).toContain(`> ${firstRow}`);
2768
+ for (let i = 0; i < 15; i++) {
2769
+ const rows = panel.render(40);
2770
+ expect(rows.length).toBeLessThanOrEqual(height);
2771
+ expect(rows.every((line) => visibleWidth(line) <= 40)).toBe(true);
2772
+ expect(rows[1]).toContain(`Footer > ${label}`);
2773
+ expect(rows.join("\n")).toContain("x Change");
2774
+ expect(rows.join("\n")).toContain("Tab Sections");
2775
+ expect(rows.join("\n")).toContain("q Back");
2776
+ expect(rows.some((line) => line.startsWith("> "))).toBe(true);
2777
+ expect(rows.join("\n")).not.toMatch(/samples?|synthetic|sonnet-long-context-preview/i);
2778
+ panel.handleInput(down);
2779
+ }
2780
+ panel.handleInput("k");
2781
+ panel.handleInput("q");
2782
+ expect(focusedRow(panel)).toContain(`> ${label}`);
2783
+ expect(closed).toBe(0);
2784
+ }
2785
+ panel.handleInput("x");
2786
+ panel.handleInput("\t");
2787
+ expect(panel.render(40)[1]).toContain("Extension statuses");
2788
+ panel.handleInput("q");
2789
+ expect(closed).toBe(1);
2790
+ expect(h.config).toEqual(before);
2791
+ expect(getKeybindings()).toBe(global);
2792
+ } finally {
2793
+ setKeybindings(previous);
2794
+ }
2795
+ },
2796
+ );
2797
+
2798
+ it("changes only Footer Starship child settings and preserves keyed status order and colors on return", async () => {
2799
+ const statuses = new Map([
2800
+ ["zeta", "Z"],
2801
+ ["alpha", "A"],
2802
+ ]);
2803
+ const h = createHarness(cloneConfig(), { getActiveExtensionStatuses: () => statuses });
2804
+ const before = structuredClone(h.config);
2805
+ const placement = vi.spyOn(h.deps, "setExtensionStatusChoice");
2806
+ const color = vi.spyOn(h.deps, "setExtensionStatusColorMode");
2807
+ await h.command().handler("segments", h.ctx);
2808
+ const panel = h.component();
2809
+ panel.handleInput("\r");
2810
+ panel.handleInput("\x1b");
2811
+ openFooterPage(panel, "Git");
2812
+ panel.handleInput("\r");
2813
+ panel.handleInput("\x1b");
2814
+ panel.handleInput("\t");
2815
+ expectFocusOrder(panel, [
2816
+ "Default placement",
2817
+ "alpha placement",
2818
+ "alpha color",
2819
+ "zeta placement",
2820
+ "zeta color",
2821
+ ]);
2822
+ selectLabel(panel, "Default placement");
2823
+ panel.handleInput("\r");
2824
+ selectLabel(panel, "alpha placement");
2825
+ panel.handleInput("\r");
2826
+ selectLabel(panel, "zeta color");
2827
+ panel.handleInput("\r");
2828
+ expect(placement).toHaveBeenCalledExactlyOnceWith("alpha", "left");
2829
+ expect(color).toHaveBeenCalledExactlyOnceWith("zeta", "original");
2830
+ const expected = structuredClone(before);
2831
+ expected.components.footer.styles.starship.segments.cwd = false;
2832
+ expected.components.footer.styles.starship.segments.gitBranch = false;
2833
+ expected.components.footer.styles.starship.extensionStatuses.defaultPlacement = "right";
2834
+ expected.components.extensionStatuses.defaultVisibility = "hide";
2835
+ expected.components.extensionStatuses.visibility.alpha = "show";
2836
+ expected.components.footer.styles.starship.extensionStatuses.placements.alpha = "left";
2837
+ expected.components.footer.styles.starship.extensionStatuses.colorModes.zeta = "original";
2838
+ expect(h.config).toEqual(expected);
2839
+ statuses.delete("alpha");
2840
+ statuses.set("beta", "B");
2841
+ panel.handleInput("\x1b[Z");
2842
+ panel.handleInput("\t");
2843
+ expectFocusOrder(panel, [
2844
+ "Default placement",
2845
+ "alpha placement",
2846
+ "alpha color",
2847
+ "beta placement",
2848
+ "beta color",
2849
+ "zeta placement",
2850
+ "zeta color",
2851
+ ]);
2852
+ expect(row(panel, "zeta color")).toContain("Original");
2853
+ });
2854
+
2855
+ it("closes a stale child without navigating, saving or reinstalling", async () => {
2856
+ const h = createHarness();
2857
+ const before = structuredClone(h.config);
2858
+ await h.command().handler("git", h.ctx);
2859
+ h.sessionLifecycle.shutdown();
2860
+ h.component().handleInput("\r");
2861
+ h.component().handleInput("\x1b");
2862
+ expect(h.doneCalls()).toBe(1);
2863
+ expect(h.config).toEqual(before);
2864
+ expect(h.calls.renders.shared).toBe(0);
2865
+ });
2866
+ });
2867
+
2868
+ describe("independent Extension statuses settings", () => {
2869
+ it.each(["native", "hidden", "starship"] as const)(
2870
+ "displays inherited positions and Off without saving across %s mode boundaries",
2871
+ async (style) => {
2872
+ for (const defaultVisibility of ["show", "hide"] as const) {
2873
+ const config = cloneConfig();
2874
+ config.components.footer.style = style;
2875
+ config.components.footer.styles.starship.extensionStatuses.defaultPlacement = "off";
2876
+ config.components.footer.styles.starship.extensionStatuses.placements.legacy = "off";
2877
+ config.components.extensionStatuses.defaultVisibility = defaultVisibility;
2878
+ config.components.extensionStatuses.hidden = { defaultPlacement: "middle" };
2879
+ const h = createHarness(config, {
2880
+ getActiveExtensionStatuses: () => new Map([["key", "RAW"]]),
2881
+ });
2882
+ const before = structuredClone(config);
2883
+ const placement = vi.spyOn(h.deps, "setExtensionStatusChoice");
2884
+ const migrate = vi.spyOn(h.deps, "migrateSelections");
2885
+ await h.command().handler("extensions", h.ctx);
2886
+ const panel = h.component();
2887
+ const effective =
2888
+ defaultVisibility === "hide" || style === "starship"
2889
+ ? "Off"
2890
+ : style === "hidden"
2891
+ ? "Middle"
2892
+ : "Right";
2893
+ for (const label of ["Default placement", "key placement", "legacy placement"])
2894
+ expect(row(panel, label).trim().split(/\s+/).at(-1)).toBe(effective);
2895
+ panel.handleInput("\x1b");
2896
+ expect(config).toEqual(before);
2897
+ expect(h.calls.extensionDefaultPlacement).toEqual([]);
2898
+ expect(placement).not.toHaveBeenCalled();
2899
+ expect(migrate).not.toHaveBeenCalled();
2900
+ }
2901
+ },
2902
+ );
2903
+
2904
+ it.each(["native", "hidden", "starship"] as const)(
2905
+ "offers exactly Left / Middle / Right / Off on both %s placement controls",
2906
+ async (style) => {
2907
+ const config = cloneConfig();
2908
+ config.components.footer.style = style;
2909
+ config.components.footer.styles.starship.extensionStatuses.defaultPlacement = "left";
2910
+ const h = createHarness(config, {
2911
+ getActiveExtensionStatuses: () => new Map([["key", "RAW"]]),
2912
+ });
2913
+ const before = structuredClone(config);
2914
+ const placement = vi.spyOn(h.deps, "setExtensionStatusChoice");
2915
+ await h.command().handler("extensions", h.ctx);
2916
+ const panel = h.component();
2917
+ expectFocusOrder(panel, ["Default placement", "key placement", "key color"]);
2918
+ expect(row(panel, "Default placement")).toMatch(/\sLeft$/);
2919
+ expect(row(panel, "key placement")).toMatch(/\sLeft$/);
2920
+ expect(config).toEqual(before);
2921
+ expect(h.calls.extensionDefaultPlacement).toEqual([]);
2922
+ expect(placement).not.toHaveBeenCalled();
2923
+ for (const label of ["Default placement", "key placement"]) {
2924
+ const choices: string[] = [];
2925
+ for (let i = 0; i < 4; i++) {
2926
+ choices.push(row(panel, label).trim().split(/\s+/).at(-1) ?? "");
2927
+ panel.handleInput("\r");
2928
+ }
2929
+ expect(choices).toEqual(["Left", "Middle", "Right", "Off"]);
2930
+ expect(row(panel, label)).toMatch(/\sLeft$/);
2931
+ }
2932
+ expect(h.calls.extensionDefaultPlacement).toEqual(["middle", "right", "off", "left"]);
2933
+ expect(placement.mock.calls.map(([, choice]) => choice)).toEqual([
2934
+ "middle",
2935
+ "right",
2936
+ "off",
2937
+ "left",
2938
+ ]);
2939
+ },
2940
+ );
2941
+
2942
+ it.each(["native", "hidden", "starship"] as const)(
2943
+ "exposes visibility and saved/observed keys under %s without changing other owners",
2944
+ async (style) => {
2945
+ const config = cloneConfig();
2946
+ config.components.footer.style = style;
2947
+ config.components.extensionStatuses.visibility = { saved: "hide" };
2948
+ config.components.footer.styles.starship.extensionStatuses.placements.legacy = "off";
2949
+ const h = createHarness(config, {
2950
+ getActiveExtensionStatuses: () => new Map([["z:third-party", "RAW"]]),
2951
+ });
2952
+ const before = structuredClone(config);
2953
+ await h.command().handler("extensions", h.ctx);
2954
+ const panel = h.component();
2955
+ expect(panel.render(40)[1]).toContain("Extension statuses");
2956
+ expectFocusOrder(panel, [
2957
+ "Default placement",
2958
+ "legacy placement",
2959
+ "legacy color",
2960
+ "saved placement",
2961
+ "saved color",
2962
+ "z:third-party placement",
2963
+ "z:third-party color",
2964
+ ]);
2965
+ expect(panel.render(100).join("\n")).not.toContain("Inactive now");
2966
+ expect(panel.render(160).join("\n")).not.toMatch(
2967
+ /Hidden placement|Starship placement|visibility/,
2968
+ );
2969
+ expect(row(panel, "legacy placement")).toContain(
2970
+ style === "starship" ? "Off" : style === "hidden" ? "Left" : "Right",
2971
+ );
2972
+ expect(config).toEqual(before);
2973
+ selectLabel(panel, "Default placement");
2974
+ for (let i = 0; i < (style === "hidden" ? 3 : 1); i++) panel.handleInput("\r");
2975
+ expect(config.components.extensionStatuses.defaultVisibility).toBe("hide");
2976
+ selectLabel(panel, "saved placement");
2977
+ panel.handleInput("\r");
2978
+ expect(config.components.extensionStatuses.visibility.saved).toBe("show");
2979
+ selectLabel(panel, "z:third-party placement");
2980
+ panel.handleInput("\r");
2981
+ expect(config.components.extensionStatuses.visibility["z:third-party"]).toBe("show");
2982
+ for (const owner of [
2983
+ "editor",
2984
+ "userMessages",
2985
+ "workingLine",
2986
+ "selectorBorders",
2987
+ "thinkingSteps",
2988
+ ] as const)
2989
+ expect(config.components[owner]).toEqual(before.components[owner]);
2990
+ expect(h.calls.footer).toEqual([]);
2991
+ panel.handleInput("\x1b");
2992
+ expect(h.doneCalls()).toBe(1);
2993
+ expect(h.command().getArgumentCompletions("extensions")).toContainEqual({
2994
+ value: "extensions",
2995
+ label: "extensions",
2996
+ });
2997
+ },
2998
+ );
2999
+ it("supports remapped Change/Close and narrow top-level navigation", async () => {
3000
+ let panel: Component | undefined;
3001
+ let closed = false;
3002
+ const h = createHarness(
3003
+ cloneConfig(),
3004
+ {},
3005
+ {
3006
+ custom: async (factory: (...args: unknown[]) => Component) => {
3007
+ panel = factory(
3008
+ { terminal: { rows: 8 }, requestRender() {} },
3009
+ theme(),
3010
+ {
3011
+ getKeys: (id: string) =>
3012
+ ({
3013
+ "tui.select.confirm": ["x"],
3014
+ "tui.select.cancel": ["q"],
3015
+ "tui.select.down": ["j"],
3016
+ "tui.select.up": ["k"],
3017
+ })[id],
3018
+ },
3019
+ () => {
3020
+ closed = true;
3021
+ },
3022
+ );
3023
+ },
3024
+ },
3025
+ );
3026
+ await h.command().handler("extensions", h.ctx);
3027
+ if (!panel) throw new Error("No panel");
3028
+ expect(panel.render(40).length).toBeLessThanOrEqual(8);
3029
+ expect(panel.render(40).every((line) => visibleWidth(line) <= 40)).toBe(true);
3030
+ panel.handleInput("x");
3031
+ expect(h.config.components.extensionStatuses.defaultVisibility).toBe("hide");
3032
+ panel.handleInput("\x1b[Z");
3033
+ expect(panel.render(40)[1]).toContain("Footer");
3034
+ panel.handleInput("\t");
3035
+ expect(panel.render(40)[1]).toContain("Extension statuses");
3036
+ panel.handleInput("q");
3037
+ expect(closed).toBe(true);
3038
+ });
3039
+ });
3040
+
3041
+ describe("Hidden extension color settings", () => {
3042
+ it("cycles Original/Zentui independently of Starship colors, visibility and placement", async () => {
3043
+ const config = cloneConfig();
3044
+ config.components.footer.style = "hidden";
3045
+ config.components.extensionStatuses.hidden = { placements: { "demo:build": "right" } };
3046
+ config.components.extensionStatuses.visibility = { "demo:build": "show" };
3047
+ const beforeFooter = structuredClone(config.components.footer);
3048
+ const h = createHarness(config, {
3049
+ getActiveExtensionStatuses: () => new Map([["demo:build", "\x1b[32mBUILD\x1b[0m"]]),
3050
+ });
3051
+ await h.command().handler("extensions", h.ctx);
3052
+ const panel = h.component();
3053
+ selectLabel(panel, "demo:build color");
3054
+ expect(row(panel, "demo:build color")).toContain("Original");
3055
+ expect(panel.render(160).join("\n")).not.toContain("Inactive now");
3056
+ panel.handleInput("\r");
3057
+ expect(row(panel, "demo:build color")).toContain("Zentui");
3058
+ expect(config.components.extensionStatuses.hidden.colorModes).toEqual({
3059
+ "demo:build": "zentui",
3060
+ });
3061
+ panel.handleInput("\r");
3062
+ expect(row(panel, "demo:build color")).toContain("Original");
3063
+ expect(config.components.extensionStatuses.hidden.colorModes).toEqual({});
3064
+ expect(config.components.extensionStatuses.hidden.placements).toEqual({
3065
+ "demo:build": "right",
3066
+ });
3067
+ expect(config.components.extensionStatuses.visibility).toEqual({ "demo:build": "show" });
3068
+ expect(config.components.footer).toEqual(beforeFooter);
3069
+ });
3070
+
3071
+ it("discovers color-only saved keys and removes their sparse override on Original", async () => {
3072
+ const config = cloneConfig();
3073
+ config.components.footer.style = "hidden";
3074
+ config.components.extensionStatuses.hidden = { colorModes: { saved: "zentui" } };
3075
+ const h = createHarness(config);
3076
+ await h.command().handler("extensions", h.ctx);
3077
+ const panel = h.component();
3078
+ selectLabel(panel, "saved color");
3079
+ expect(row(panel, "saved color")).toContain("Zentui");
3080
+ panel.handleInput("\r");
3081
+ expect(config.components.extensionStatuses.hidden.colorModes).toEqual({});
3082
+ expect(panel.render(160).join("\n")).not.toContain("saved color");
3083
+ expect(panel.render(160).join("\n")).toContain("No observed statuses");
3084
+ });
3085
+ });
3086
+
3087
+ describe("Hidden extension placement settings", () => {
3088
+ it("shows only active Hidden placement controls and turns off a saved unobserved key", async () => {
3089
+ const config = cloneConfig();
3090
+ config.components.footer.style = "hidden";
3091
+ config.components.extensionStatuses.hidden = {
3092
+ defaultPlacement: "right",
3093
+ placements: { saved: "right" },
3094
+ };
3095
+ const beforeFooter = structuredClone(config.components.footer);
3096
+ const h = createHarness(config);
3097
+ await h.command().handler("extensions", h.ctx);
3098
+ const panel = h.component();
3099
+ expectFocusOrder(panel, ["Default placement", "saved placement", "saved color"]);
3100
+ selectLabel(panel, "saved placement");
3101
+ expect(panel.render(160).join("\n")).not.toContain("Starship placement");
3102
+ expect(row(panel, "saved placement")).toContain("Right");
3103
+ panel.handleInput("\r");
3104
+ expect(row(panel, "saved placement")).toContain("Off");
3105
+ expect(config.components.extensionStatuses.hidden.placements).toEqual({ saved: "right" });
3106
+ selectLabel(panel, "Default placement");
3107
+ panel.handleInput("\r"); // Right -> Off; previous Hidden position remains saved
3108
+ expect(config.components.extensionStatuses.defaultVisibility).toBe("hide");
3109
+ expect(config.components.extensionStatuses.hidden.defaultPlacement).toBe("right");
3110
+ panel.handleInput("\r"); // Off -> Left
3111
+ expect(config.components.extensionStatuses.hidden.defaultPlacement).toBe("left");
3112
+ expect(config.components.footer).toEqual(beforeFooter);
3113
+ expect(config.components.extensionStatuses.visibility).toEqual({ saved: "hide" });
3114
+ });
3115
+ });