@selesai/code 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/cli/credential-print.js +4 -4
  3. package/dist/cli/startup-ui.js +2 -1
  4. package/dist/cli.js +0 -0
  5. package/dist/core/agent-session.d.ts +12 -1
  6. package/dist/core/agent-session.js +77 -9
  7. package/dist/core/compaction/branch-summarization.js +34 -33
  8. package/dist/core/compaction/compaction.d.ts +5 -0
  9. package/dist/core/compaction/compaction.js +100 -85
  10. package/dist/core/compaction/utils.js +2 -2
  11. package/dist/core/export-html/template.css +1066 -1066
  12. package/dist/core/export-html/template.html +55 -55
  13. package/dist/core/export-html/template.js +1864 -1864
  14. package/dist/core/export-html/vendor/highlight.min.js +1212 -1212
  15. package/dist/core/export-html/vendor/marked.min.js +78 -78
  16. package/dist/core/extensions/index.d.ts +1 -1
  17. package/dist/core/extensions/runner.d.ts +5 -0
  18. package/dist/core/extensions/runner.js +48 -1
  19. package/dist/core/extensions/types.d.ts +18 -1
  20. package/dist/core/llama/client.d.ts +6 -0
  21. package/dist/core/llama/client.js +7 -0
  22. package/dist/core/llama/provider.d.ts +3 -1
  23. package/dist/core/llama/provider.js +28 -6
  24. package/dist/core/messages.js +7 -7
  25. package/dist/core/session-manager.js +4 -2
  26. package/dist/core/settings-manager.d.ts +8 -1
  27. package/dist/core/settings-manager.js +17 -0
  28. package/dist/defaults/models.json +32 -9
  29. package/dist/defaults/settings.json +0 -3
  30. package/dist/extensions/auto-session-name.test.ts +157 -0
  31. package/dist/extensions/auto-session-name.ts +96 -0
  32. package/dist/extensions/context-compaction-reminder.test.ts +82 -82
  33. package/dist/extensions/context-compaction-reminder.ts +28 -28
  34. package/dist/extensions/cost-reconcile.test.ts +76 -0
  35. package/dist/extensions/cost-reconcile.ts +278 -0
  36. package/dist/extensions/enable-readonly-tools.test.ts +11 -0
  37. package/dist/extensions/enable-readonly-tools.ts +7 -3
  38. package/dist/extensions/package.json +3 -0
  39. package/dist/extensions/pi-intercom/LICENSE +21 -21
  40. package/dist/extensions/pi-intercom/broker/client.test.ts +83 -83
  41. package/dist/extensions/pi-intercom/broker/framing.test.ts +114 -114
  42. package/dist/extensions/pi-intercom/broker/paths.ts +134 -134
  43. package/dist/extensions/pi-intercom/broker/runtime-claim.test.ts +34 -34
  44. package/dist/extensions/pi-intercom/broker/runtime-claim.ts +21 -21
  45. package/dist/extensions/pi-intercom/cwd.test.ts +40 -40
  46. package/dist/extensions/pi-intercom/cwd.ts +31 -31
  47. package/dist/extensions/pi-intercom/format-context.test.ts +31 -31
  48. package/dist/extensions/pi-intercom/format-context.ts +32 -32
  49. package/dist/extensions/pi-intercom/test/overlay-width.test.ts +66 -66
  50. package/dist/extensions/pi-intercom/ui/compose.ts +143 -143
  51. package/dist/extensions/pi-intercom/ui/session-list.ts +166 -166
  52. package/dist/extensions/pi-rewind-hook/README.md +245 -245
  53. package/dist/extensions/pi-rewind-hook/index.ts +1445 -1445
  54. package/dist/extensions/pi-rewind-hook/package.json +29 -29
  55. package/dist/extensions/pi-subagents/install.mjs +0 -0
  56. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  57. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  58. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  59. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  60. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  61. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  62. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  63. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  64. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  65. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  66. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  67. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  68. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  69. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  70. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  71. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  72. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  73. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  74. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  75. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  76. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  77. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  78. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  79. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  80. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  81. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  82. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  83. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  84. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  85. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  86. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  87. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  88. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  89. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  90. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  91. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  92. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  93. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  94. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  95. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  96. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  97. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  98. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  99. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  100. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  101. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  102. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  103. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  104. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  105. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  106. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  107. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  108. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  109. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  110. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  111. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  112. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  113. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  114. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  115. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  116. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  117. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  118. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  119. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  120. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  121. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  122. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  123. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  124. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  125. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  126. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  127. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  128. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  129. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  130. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  131. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  132. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  133. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  134. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  135. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  136. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  137. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  138. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  139. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  140. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  141. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  142. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  143. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  144. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  145. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  146. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  147. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  148. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  149. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  150. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  151. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  152. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  153. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  154. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  155. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  156. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  157. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  158. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  159. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  160. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  161. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  162. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  163. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  164. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  165. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  166. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  167. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  168. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  169. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  170. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  171. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  172. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  173. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  174. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  175. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  176. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  177. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  178. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  179. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  180. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  181. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  182. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  183. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  184. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  231. package/dist/extensions/pi-tool-display/CHANGELOG.md +329 -0
  232. package/dist/extensions/pi-tool-display/LICENSE +21 -0
  233. package/dist/extensions/pi-tool-display/README.md +417 -0
  234. package/dist/extensions/pi-tool-display/config/config.example.json +40 -0
  235. package/dist/extensions/pi-tool-display/index.ts +3 -0
  236. package/dist/extensions/pi-tool-display/package-lock.json +2555 -0
  237. package/dist/extensions/pi-tool-display/package.json +86 -0
  238. package/dist/extensions/pi-tool-display/src/agent-dir.ts +35 -0
  239. package/dist/extensions/pi-tool-display/src/ansi-utils.ts +116 -0
  240. package/dist/extensions/pi-tool-display/src/bash-display.ts +213 -0
  241. package/dist/extensions/pi-tool-display/src/capabilities.ts +88 -0
  242. package/dist/extensions/pi-tool-display/src/config-modal.ts +541 -0
  243. package/dist/extensions/pi-tool-display/src/config-store.ts +304 -0
  244. package/dist/extensions/pi-tool-display/src/debug-logger.ts +150 -0
  245. package/dist/extensions/pi-tool-display/src/diff-presentation.ts +72 -0
  246. package/dist/extensions/pi-tool-display/src/diff-renderer.ts +2517 -0
  247. package/dist/extensions/pi-tool-display/src/disposable.ts +34 -0
  248. package/dist/extensions/pi-tool-display/src/extension-lifecycle.ts +14 -0
  249. package/dist/extensions/pi-tool-display/src/index.ts +109 -0
  250. package/dist/extensions/pi-tool-display/src/line-width-safety.ts +93 -0
  251. package/dist/extensions/pi-tool-display/src/modal-icons.ts +57 -0
  252. package/dist/extensions/pi-tool-display/src/pending-diff-preview.ts +370 -0
  253. package/dist/extensions/pi-tool-display/src/presets.ts +117 -0
  254. package/dist/extensions/pi-tool-display/src/render-utils.ts +186 -0
  255. package/dist/extensions/pi-tool-display/src/settings-inspector-modal.ts +475 -0
  256. package/dist/extensions/pi-tool-display/src/thinking-label.ts +343 -0
  257. package/dist/extensions/pi-tool-display/src/tool-call-box.ts +181 -0
  258. package/dist/extensions/pi-tool-display/src/tool-metadata.ts +139 -0
  259. package/dist/extensions/pi-tool-display/src/tool-overrides.ts +2168 -0
  260. package/dist/extensions/pi-tool-display/src/types.ts +109 -0
  261. package/dist/extensions/pi-tool-display/src/user-message-box-markdown.ts +64 -0
  262. package/dist/extensions/pi-tool-display/src/user-message-box-native.ts +66 -0
  263. package/dist/extensions/pi-tool-display/src/user-message-box-patch.ts +72 -0
  264. package/dist/extensions/pi-tool-display/src/user-message-box-renderer.ts +419 -0
  265. package/dist/extensions/pi-tool-display/src/user-message-box-utils.ts +106 -0
  266. package/dist/extensions/pi-tool-display/src/write-display-utils.ts +31 -0
  267. package/dist/extensions/pi-tool-display/src/zellij-modal.ts +1027 -0
  268. package/dist/extensions/pi-tool-display/tests/active-backlog-red.test.ts +65 -0
  269. package/dist/extensions/pi-tool-display/tests/ansi-utils.test.ts +345 -0
  270. package/dist/extensions/pi-tool-display/tests/bash-display.test.ts +442 -0
  271. package/dist/extensions/pi-tool-display/tests/capabilities-edge.test.ts +360 -0
  272. package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +54 -0
  273. package/dist/extensions/pi-tool-display/tests/config-modal.test.ts +360 -0
  274. package/dist/extensions/pi-tool-display/tests/config-store.test.ts +87 -0
  275. package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +415 -0
  276. package/dist/extensions/pi-tool-display/tests/debug-logger-edge.test.ts +630 -0
  277. package/dist/extensions/pi-tool-display/tests/debug-logger.test.ts +62 -0
  278. package/dist/extensions/pi-tool-display/tests/diff-renderer-ansi.test.ts +55 -0
  279. package/dist/extensions/pi-tool-display/tests/diff-renderer-edge.test.ts +886 -0
  280. package/dist/extensions/pi-tool-display/tests/diff-renderer-numbering.test.ts +135 -0
  281. package/dist/extensions/pi-tool-display/tests/diff-renderer-width.test.ts +454 -0
  282. package/dist/extensions/pi-tool-display/tests/diff-renderer-wrap.test.ts +169 -0
  283. package/dist/extensions/pi-tool-display/tests/index-integration.test.ts +354 -0
  284. package/dist/extensions/pi-tool-display/tests/pending-diff-preview.test.ts +79 -0
  285. package/dist/extensions/pi-tool-display/tests/presets-edge.test.ts +229 -0
  286. package/dist/extensions/pi-tool-display/tests/presets.test.ts +26 -0
  287. package/dist/extensions/pi-tool-display/tests/reload-behavior.test.ts +1241 -0
  288. package/dist/extensions/pi-tool-display/tests/render-utils.test.ts +710 -0
  289. package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +450 -0
  290. package/dist/extensions/pi-tool-display/tests/thinking-label-edge.test.ts +904 -0
  291. package/dist/extensions/pi-tool-display/tests/thinking-label.test.ts +72 -0
  292. package/dist/extensions/pi-tool-display/tests/tool-call-box.test.ts +105 -0
  293. package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +613 -0
  294. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +499 -0
  295. package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +315 -0
  296. package/dist/extensions/pi-tool-display/tests/tool-overrides-write-meta.test.ts +68 -0
  297. package/dist/extensions/pi-tool-display/tests/tool-ui-utils.test.ts +413 -0
  298. package/dist/extensions/pi-tool-display/tests/user-message-box-performance-red.test.ts +176 -0
  299. package/dist/extensions/pi-tool-display/tests/user-message-box.test.ts +908 -0
  300. package/dist/extensions/pi-tool-display/tests/zellij-modal.test.ts +848 -0
  301. package/dist/extensions/pi-tool-display/tool-display-api-consumer.d.ts +30 -0
  302. package/dist/extensions/pi-tool-display/tool-display-api-consumer.js +40 -0
  303. package/dist/extensions/pi-web-agent/package.json +31 -31
  304. package/dist/extensions/pi-web-agent/src/backends/config.ts +205 -205
  305. package/dist/extensions/pi-web-agent/src/backends/doctor.ts +136 -136
  306. package/dist/extensions/pi-web-agent/src/backends/factory.ts +152 -152
  307. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +25 -25
  308. package/dist/extensions/pi-web-agent/src/cache/ttl-cache.ts +28 -28
  309. package/dist/extensions/pi-web-agent/src/changelog-notice.ts +136 -136
  310. package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +946 -946
  311. package/dist/extensions/pi-web-agent/src/extension.ts +126 -126
  312. package/dist/extensions/pi-web-agent/src/extract/readability.ts +118 -118
  313. package/dist/extensions/pi-web-agent/src/fetch/browser-resolution.ts +199 -199
  314. package/dist/extensions/pi-web-agent/src/fetch/firecrawl-fetch.ts +100 -100
  315. package/dist/extensions/pi-web-agent/src/fetch/headless-fetch.ts +117 -117
  316. package/dist/extensions/pi-web-agent/src/fetch/http-fetch.ts +67 -67
  317. package/dist/extensions/pi-web-agent/src/orchestration/answer-synthesizer.ts +60 -60
  318. package/dist/extensions/pi-web-agent/src/orchestration/candidate-selector.ts +50 -50
  319. package/dist/extensions/pi-web-agent/src/orchestration/direct-url.ts +52 -52
  320. package/dist/extensions/pi-web-agent/src/orchestration/evidence-quality.ts +105 -105
  321. package/dist/extensions/pi-web-agent/src/orchestration/evidence-ranker.ts +45 -45
  322. package/dist/extensions/pi-web-agent/src/orchestration/index.ts +28 -28
  323. package/dist/extensions/pi-web-agent/src/orchestration/query-planner.ts +47 -47
  324. package/dist/extensions/pi-web-agent/src/orchestration/research-orchestrator.ts +376 -376
  325. package/dist/extensions/pi-web-agent/src/orchestration/research-types.ts +64 -64
  326. package/dist/extensions/pi-web-agent/src/orchestration/research-worker.ts +181 -181
  327. package/dist/extensions/pi-web-agent/src/orchestration/source-profile.ts +101 -101
  328. package/dist/extensions/pi-web-agent/src/orchestration/stop-decider.ts +81 -81
  329. package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +210 -210
  330. package/dist/extensions/pi-web-agent/src/presentation/config.ts +75 -75
  331. package/dist/extensions/pi-web-agent/src/presentation/explore-presentation.ts +61 -61
  332. package/dist/extensions/pi-web-agent/src/presentation/fetch-presentation.ts +54 -54
  333. package/dist/extensions/pi-web-agent/src/presentation/search-presentation.ts +41 -41
  334. package/dist/extensions/pi-web-agent/src/presentation/select-view.ts +20 -20
  335. package/dist/extensions/pi-web-agent/src/presentation/types.ts +63 -63
  336. package/dist/extensions/pi-web-agent/src/search/brave.ts +114 -114
  337. package/dist/extensions/pi-web-agent/src/search/duckduckgo.ts +72 -72
  338. package/dist/extensions/pi-web-agent/src/search/searxng.ts +96 -96
  339. package/dist/extensions/pi-web-agent/src/tools/web-explore.ts +71 -71
  340. package/dist/extensions/pi-web-agent/src/tools/web-fetch-headless.ts +31 -31
  341. package/dist/extensions/pi-web-agent/src/tools/web-fetch.ts +31 -31
  342. package/dist/extensions/pi-web-agent/src/tools/web-search.ts +157 -157
  343. package/dist/extensions/pi-web-agent/src/types.ts +88 -88
  344. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +46 -1
  345. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +10 -0
  346. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +1 -1
  347. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +3 -3
  348. package/dist/extensions/pi-zentui/test/format.test.ts +50 -2
  349. package/dist/extensions/ponytail/package.json +8 -8
  350. package/dist/extensions/question/constants.ts +30 -30
  351. package/dist/extensions/question/helpers.ts +58 -58
  352. package/dist/extensions/question/navigation.ts +14 -14
  353. package/dist/extensions/question/package.json +19 -19
  354. package/dist/extensions/question/selection-mode.ts +46 -46
  355. package/dist/extensions/question/shortcuts.ts +44 -44
  356. package/dist/extensions/question/types.ts +132 -132
  357. package/dist/extensions/test-resolve-hook-impl.mjs +6 -6
  358. package/dist/extensions/test-resolve-hook.mjs +6 -6
  359. package/dist/extensions/tokenin-onboarding.ts +112 -2
  360. package/dist/extensions/web-agent-onboarding.ts +222 -222
  361. package/dist/index.d.ts +2 -1
  362. package/dist/index.js +1 -0
  363. package/dist/main.js +2 -0
  364. package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  365. package/dist/modes/interactive/components/settings-selector.js +10 -0
  366. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  367. package/dist/modes/interactive/interactive-mode.js +72 -42
  368. package/dist/modes/rpc/rpc-client.d.ts +7 -0
  369. package/dist/modes/rpc/rpc-client.js +7 -0
  370. package/dist/modes/rpc/rpc-mode.js +3 -0
  371. package/dist/modes/rpc/rpc-types.d.ts +12 -0
  372. package/dist/package-manager-cli.js +71 -71
  373. package/dist/rpc-entry.js +0 -0
  374. package/dist/skills/improve-codebase/REFERENCE.md +78 -78
  375. package/dist/utils/shell.js +6 -4
  376. package/docs/compaction.md +396 -396
  377. package/docs/containerization.md +111 -111
  378. package/docs/development.md +71 -71
  379. package/docs/docs.json +164 -164
  380. package/docs/environment-variables.md +86 -86
  381. package/docs/index.md +83 -83
  382. package/docs/json.md +82 -82
  383. package/docs/models.md +502 -502
  384. package/docs/packages.md +227 -227
  385. package/docs/plans/subagent-delegation/phase-0-correctness.md +264 -264
  386. package/docs/plans/subagent-delegation/phase-1-behavioral-contract.md +485 -485
  387. package/docs/plans/subagent-delegation/phase-2-context-controls.md +281 -281
  388. package/docs/plans/subagent-delegation/phase-3-advisory-routing.md +361 -361
  389. package/docs/plans/subagent-delegation/phase-4-optional-enforcement.md +380 -380
  390. package/docs/prompt-templates.md +95 -95
  391. package/docs/providers.md +293 -293
  392. package/docs/security.md +59 -59
  393. package/docs/session-format.md +414 -414
  394. package/docs/sessions.md +145 -145
  395. package/docs/settings.md +4 -0
  396. package/docs/shared-host-extensions.md +109 -109
  397. package/docs/shell-aliases.md +13 -13
  398. package/docs/skills.md +231 -231
  399. package/docs/terminal-setup.md +142 -142
  400. package/docs/termux.md +127 -127
  401. package/docs/themes.md +295 -295
  402. package/docs/tmux.md +63 -63
  403. package/docs/tui.md +927 -927
  404. package/docs/windows.md +17 -17
  405. package/examples/README.md +25 -25
  406. package/examples/extensions/README.md +211 -211
  407. package/examples/extensions/auto-commit-on-exit.ts +49 -49
  408. package/examples/extensions/bash-spawn-hook.ts +30 -30
  409. package/examples/extensions/bookmark.ts +50 -50
  410. package/examples/extensions/border-status-editor.ts +150 -150
  411. package/examples/extensions/built-in-tool-renderer.ts +249 -249
  412. package/examples/extensions/claude-rules.ts +86 -86
  413. package/examples/extensions/commands.ts +72 -72
  414. package/examples/extensions/confirm-destructive.ts +59 -59
  415. package/examples/extensions/custom-compaction.ts +130 -130
  416. package/examples/extensions/custom-footer.ts +64 -64
  417. package/examples/extensions/custom-header.ts +73 -73
  418. package/examples/extensions/custom-provider-anthropic/index.ts +610 -610
  419. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -24
  420. package/examples/extensions/custom-provider-anthropic/package.json +19 -19
  421. package/examples/extensions/custom-provider-gitlab-duo/index.ts +404 -404
  422. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -16
  423. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -82
  424. package/examples/extensions/dirty-repo-guard.ts +56 -56
  425. package/examples/extensions/doom-overlay/README.md +46 -46
  426. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -21
  427. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  428. package/examples/extensions/doom-overlay/doom/build.sh +152 -152
  429. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -72
  430. package/examples/extensions/doom-overlay/doom-component.ts +132 -132
  431. package/examples/extensions/doom-overlay/doom-engine.ts +173 -173
  432. package/examples/extensions/doom-overlay/doom-keys.ts +104 -104
  433. package/examples/extensions/doom-overlay/index.ts +74 -74
  434. package/examples/extensions/doom-overlay/wad-finder.ts +51 -51
  435. package/examples/extensions/dynamic-resources/SKILL.md +8 -8
  436. package/examples/extensions/dynamic-resources/dynamic.json +79 -79
  437. package/examples/extensions/dynamic-resources/dynamic.md +5 -5
  438. package/examples/extensions/dynamic-resources/index.ts +15 -15
  439. package/examples/extensions/dynamic-tools.ts +74 -74
  440. package/examples/extensions/event-bus.ts +43 -43
  441. package/examples/extensions/file-trigger.ts +41 -41
  442. package/examples/extensions/git-checkpoint.ts +53 -53
  443. package/examples/extensions/git-merge-and-resolve.ts +115 -115
  444. package/examples/extensions/github-issue-autocomplete.ts +185 -185
  445. package/examples/extensions/gondolin/index.ts +531 -531
  446. package/examples/extensions/gondolin/package-lock.json +185 -185
  447. package/examples/extensions/gondolin/package.json +19 -19
  448. package/examples/extensions/handoff.ts +199 -199
  449. package/examples/extensions/hello.ts +26 -26
  450. package/examples/extensions/hidden-thinking-label.ts +53 -53
  451. package/examples/extensions/inline-bash.ts +94 -94
  452. package/examples/extensions/input-transform-streaming.ts +39 -39
  453. package/examples/extensions/input-transform.ts +43 -43
  454. package/examples/extensions/interactive-shell.ts +196 -196
  455. package/examples/extensions/mac-system-theme.ts +47 -47
  456. package/examples/extensions/message-renderer.ts +59 -59
  457. package/examples/extensions/minimal-mode.ts +426 -426
  458. package/examples/extensions/modal-editor.ts +85 -85
  459. package/examples/extensions/model-status.ts +31 -31
  460. package/examples/extensions/notify.ts +55 -55
  461. package/examples/extensions/overlay-qa-tests.ts +1450 -1450
  462. package/examples/extensions/overlay-test.ts +153 -153
  463. package/examples/extensions/permission-gate.ts +34 -34
  464. package/examples/extensions/pirate.ts +47 -47
  465. package/examples/extensions/plan-mode/README.md +66 -66
  466. package/examples/extensions/plan-mode/index.ts +390 -390
  467. package/examples/extensions/plan-mode/utils.ts +168 -168
  468. package/examples/extensions/preset.ts +436 -436
  469. package/examples/extensions/project-trust.ts +64 -64
  470. package/examples/extensions/prompt-customizer.ts +97 -97
  471. package/examples/extensions/protected-paths.ts +30 -30
  472. package/examples/extensions/provider-payload.ts +18 -18
  473. package/examples/extensions/qna.ts +122 -122
  474. package/examples/extensions/question.ts +285 -285
  475. package/examples/extensions/questionnaire.ts +448 -448
  476. package/examples/extensions/rainbow-editor.ts +88 -88
  477. package/examples/extensions/reload-runtime.ts +37 -37
  478. package/examples/extensions/rpc-demo.ts +118 -118
  479. package/examples/extensions/sandbox/index.ts +321 -321
  480. package/examples/extensions/sandbox/package-lock.json +92 -92
  481. package/examples/extensions/sandbox/package.json +19 -19
  482. package/examples/extensions/send-user-message.ts +97 -97
  483. package/examples/extensions/session-name.ts +27 -27
  484. package/examples/extensions/shutdown-command.ts +63 -63
  485. package/examples/extensions/snake.ts +343 -343
  486. package/examples/extensions/space-invaders.ts +560 -560
  487. package/examples/extensions/ssh.ts +220 -220
  488. package/examples/extensions/status-line.ts +32 -32
  489. package/examples/extensions/structured-output.ts +65 -65
  490. package/examples/extensions/subagent/README.md +175 -175
  491. package/examples/extensions/subagent/agents/planner.md +37 -37
  492. package/examples/extensions/subagent/agents/reviewer.md +35 -35
  493. package/examples/extensions/subagent/agents/scout.md +50 -50
  494. package/examples/extensions/subagent/agents/worker.md +24 -24
  495. package/examples/extensions/subagent/agents.ts +126 -126
  496. package/examples/extensions/subagent/index.ts +1015 -1015
  497. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -10
  498. package/examples/extensions/subagent/prompts/implement.md +10 -10
  499. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -9
  500. package/examples/extensions/summarize.ts +209 -209
  501. package/examples/extensions/system-prompt-header.ts +17 -17
  502. package/examples/extensions/tic-tac-toe.ts +1008 -1008
  503. package/examples/extensions/timed-confirm.ts +70 -70
  504. package/examples/extensions/titlebar-spinner.ts +58 -58
  505. package/examples/extensions/todo.ts +297 -297
  506. package/examples/extensions/tool-override.ts +144 -144
  507. package/examples/extensions/tools.ts +146 -146
  508. package/examples/extensions/trigger-compact.ts +50 -50
  509. package/examples/extensions/truncated-tool.ts +195 -195
  510. package/examples/extensions/widget-placement.ts +9 -9
  511. package/examples/extensions/with-deps/index.ts +32 -32
  512. package/examples/extensions/with-deps/package-lock.json +31 -31
  513. package/examples/extensions/with-deps/package.json +22 -22
  514. package/examples/extensions/working-indicator.ts +123 -123
  515. package/examples/extensions/working-message-test.ts +25 -25
  516. package/examples/rpc-extension-ui.ts +632 -632
  517. package/examples/sdk/01-minimal.ts +26 -26
  518. package/examples/sdk/02-custom-model.ts +53 -53
  519. package/examples/sdk/03-custom-prompt.ts +75 -75
  520. package/examples/sdk/04-skills.ts +55 -55
  521. package/examples/sdk/05-tools.ts +48 -48
  522. package/examples/sdk/06-extensions.ts +99 -99
  523. package/examples/sdk/07-context-files.ts +47 -47
  524. package/examples/sdk/08-prompt-templates.ts +51 -51
  525. package/examples/sdk/09-api-keys-and-oauth.ts +52 -52
  526. package/examples/sdk/10-settings.ts +53 -53
  527. package/examples/sdk/11-sessions.ts +52 -52
  528. package/examples/sdk/12-full-control.ts +79 -79
  529. package/examples/sdk/13-session-runtime.ts +67 -67
  530. package/examples/sdk/README.md +144 -144
  531. package/package.json +6 -6
@@ -0,0 +1,1027 @@
1
+ // Vendored from ../zellij-modal/index.ts to keep pi-tool-display standalone.
2
+ // Keep this module in sync when upstream zellij-modal primitives change.
3
+ import { getSettingsListTheme, type ExtensionAPI, type Theme } from "@earendil-works/pi-coding-agent";
4
+ import {
5
+ Box,
6
+ Container,
7
+ SettingsList,
8
+ Spacer,
9
+ Text,
10
+ truncateToWidth,
11
+ visibleWidth,
12
+ type SettingItem,
13
+ } from "@earendil-works/pi-tui";
14
+
15
+ const ANSI_RESET = "\x1b[0m";
16
+
17
+ /**
18
+ * Border character set used to render a modal frame.
19
+ */
20
+ export interface BorderCharacters {
21
+ /** Top-left corner. */
22
+ topLeft: string;
23
+ /** Top-right corner. */
24
+ topRight: string;
25
+ /** Bottom-left corner. */
26
+ bottomLeft: string;
27
+ /** Bottom-right corner. */
28
+ bottomRight: string;
29
+ /** Horizontal line character. */
30
+ horizontal: string;
31
+ /** Vertical line character. */
32
+ vertical: string;
33
+ /** Optional left tee junction. */
34
+ verticalLeft?: string;
35
+ /** Optional right tee junction. */
36
+ verticalRight?: string;
37
+ }
38
+
39
+ /**
40
+ * Predefined border character sets aligned with Zellij styles.
41
+ */
42
+ export const BORDER_STYLES = {
43
+ rounded: {
44
+ topLeft: "╭",
45
+ topRight: "╮",
46
+ bottomLeft: "╰",
47
+ bottomRight: "╯",
48
+ horizontal: "─",
49
+ vertical: "│",
50
+ verticalLeft: "├",
51
+ verticalRight: "┤",
52
+ },
53
+ square: {
54
+ topLeft: "┌",
55
+ topRight: "┐",
56
+ bottomLeft: "└",
57
+ bottomRight: "┘",
58
+ horizontal: "─",
59
+ vertical: "│",
60
+ verticalLeft: "├",
61
+ verticalRight: "┤",
62
+ },
63
+ double: {
64
+ topLeft: "╔",
65
+ topRight: "╗",
66
+ bottomLeft: "╚",
67
+ bottomRight: "╝",
68
+ horizontal: "═",
69
+ vertical: "║",
70
+ },
71
+ none: {
72
+ topLeft: " ",
73
+ topRight: " ",
74
+ bottomLeft: " ",
75
+ bottomRight: " ",
76
+ horizontal: " ",
77
+ vertical: " ",
78
+ },
79
+ } as const satisfies Record<string, BorderCharacters>;
80
+
81
+ /**
82
+ * Name of a supported border style.
83
+ */
84
+ export type BorderStyle = keyof typeof BORDER_STYLES;
85
+
86
+ /**
87
+ * Supported palette color formats.
88
+ */
89
+ export type PaletteColor =
90
+ | { type: "rgb"; r: number; g: number; b: number }
91
+ | { type: "8bit"; code: number }
92
+ | { type: "named"; name: string };
93
+
94
+ /**
95
+ * Semantic color slots for a Zellij-style modal.
96
+ */
97
+ export interface ZellijColorPalette {
98
+ /** Primary foreground text. */
99
+ fg: PaletteColor;
100
+ /** Modal background. */
101
+ bg: PaletteColor;
102
+ /** Accent / selection color. */
103
+ accent: PaletteColor;
104
+ /** Secondary text color. */
105
+ muted: PaletteColor;
106
+ /** Tertiary text color. */
107
+ dim: PaletteColor;
108
+ /** Success state color. */
109
+ success: PaletteColor;
110
+ /** Error state color. */
111
+ error: PaletteColor;
112
+ /** Warning state color. */
113
+ warning: PaletteColor;
114
+ /** Default border color. */
115
+ border: PaletteColor;
116
+ /** Border color when focused. */
117
+ borderFocused: PaletteColor;
118
+ /** Border color when unfocused. */
119
+ borderUnfocused: PaletteColor;
120
+ }
121
+
122
+ /**
123
+ * Default Zellij-inspired palette.
124
+ */
125
+ export const DEFAULT_ZELLIJ_PALETTE: ZellijColorPalette = {
126
+ fg: { type: "named", name: "white" },
127
+ bg: { type: "named", name: "black" },
128
+ accent: { type: "8bit", code: 36 },
129
+ muted: { type: "8bit", code: 245 },
130
+ dim: { type: "8bit", code: 238 },
131
+ success: { type: "8bit", code: 154 },
132
+ error: { type: "8bit", code: 124 },
133
+ warning: { type: "8bit", code: 166 },
134
+ border: { type: "8bit", code: 238 },
135
+ borderFocused: { type: "8bit", code: 154 },
136
+ borderUnfocused: { type: "8bit", code: 238 },
137
+ };
138
+
139
+ /**
140
+ * A title segment in the top border.
141
+ */
142
+ export interface TitleSegment {
143
+ /** Segment text. */
144
+ text: string;
145
+ /** Segment foreground color slot or explicit color. */
146
+ color: keyof ZellijColorPalette | PaletteColor;
147
+ /** Optional segment background color. */
148
+ bgColor?: PaletteColor;
149
+ /** Enables bold style. */
150
+ bold?: boolean;
151
+ /** Truncation strategy when segment text is too long. */
152
+ truncate?: "start" | "middle" | "end" | "none";
153
+ /** Maximum visible width for text content (0 means unlimited). */
154
+ maxWidth?: number;
155
+ }
156
+
157
+ /**
158
+ * Three-part title bar configuration.
159
+ */
160
+ export interface TitleBarConfig {
161
+ /** Left segment (usually title). */
162
+ left?: TitleSegment | string;
163
+ /** Center segment (usually status). */
164
+ center?: TitleSegment | string;
165
+ /** Right segment (usually counters/actions). */
166
+ right?: TitleSegment | string;
167
+ /** Optional textual separator (reserved for custom renderers). */
168
+ separator?: string;
169
+ }
170
+
171
+ /**
172
+ * Help text line rendered in the bottom border.
173
+ */
174
+ export interface HelpUndertitleConfig {
175
+ /** Static help text. */
176
+ text?: string;
177
+ /** Dynamic help text generator. */
178
+ textGenerator?: (width: number) => string;
179
+ /** Progressive truncation variants from longest to shortest. */
180
+ variants?: string[];
181
+ /** Structured key hints for help text generation. */
182
+ keyHints?: Array<{
183
+ key: string;
184
+ description: string;
185
+ }>;
186
+ /** Separator between key hints. */
187
+ keyHintSeparator?: string;
188
+ /** Palette slot for help text color. */
189
+ color?: keyof ZellijColorPalette;
190
+ }
191
+
192
+ /**
193
+ * Full modal configuration.
194
+ */
195
+ export interface ZellijModalConfig {
196
+ /** Border style preset. */
197
+ borderStyle: BorderStyle;
198
+ /** Active color palette. */
199
+ palette: ZellijColorPalette;
200
+ /** Focus state for frame highlighting. */
201
+ focused: boolean;
202
+ /** Internal content padding. */
203
+ padding: number;
204
+ /** Top title bar config. */
205
+ titleBar: TitleBarConfig;
206
+ /** Optional bottom help line config. */
207
+ helpUndertitle?: HelpUndertitleConfig;
208
+ /** Minimum preferred modal width. */
209
+ minWidth: number;
210
+ /** Maximum modal width (0 means no explicit max). */
211
+ maxWidth: number;
212
+ /** Overlay options for `ctx.ui.custom()`. */
213
+ overlay: {
214
+ anchor: "center" | "top" | "bottom";
215
+ width: number | string;
216
+ maxHeight: number | string;
217
+ margin: number;
218
+ };
219
+ }
220
+
221
+ /**
222
+ * Partial modal configuration used by consumers.
223
+ */
224
+ export type ZellijModalConfigPartial = Partial<ZellijModalConfig> & {
225
+ /** Shorthand for `titleBar.left`. */
226
+ title?: string;
227
+ /** Shorthand for help text. */
228
+ helpText?: string | HelpUndertitleConfig;
229
+ };
230
+
231
+ /**
232
+ * Modal rendering metadata.
233
+ */
234
+ export interface ZellijModalRenderOutput {
235
+ /** Fully rendered lines. */
236
+ lines: string[];
237
+ /** Visible frame width. */
238
+ visibleWidth: number;
239
+ /** Width of content area inside borders and padding. */
240
+ contentWidth: number;
241
+ /** Inclusive index of first content line. */
242
+ contentStartLine: number;
243
+ /** Inclusive index of last content line. */
244
+ contentEndLine: number;
245
+ }
246
+
247
+ /**
248
+ * Minimal content renderer contract for modal content.
249
+ */
250
+ export interface ZellijModalContentRenderer {
251
+ /** Render content into lines for the given width. */
252
+ render(width: number): string[];
253
+ /** Invalidate internal caches. */
254
+ invalidate(): void;
255
+ /** Optional input handler. */
256
+ handleInput?(data: string): void;
257
+ }
258
+
259
+ /**
260
+ * Full modal component contract.
261
+ */
262
+ export interface ZellijModalComponent extends ZellijModalContentRenderer {
263
+ /** Effective modal configuration. */
264
+ config: ZellijModalConfig;
265
+ /** Wrapped content renderer. */
266
+ content: ZellijModalContentRenderer;
267
+ /** Render complete modal output. */
268
+ renderModal(width: number): ZellijModalRenderOutput;
269
+ /** Release resources. */
270
+ dispose(): void;
271
+ }
272
+
273
+ /**
274
+ * Theme helper for modal-specific color resolution and ANSI formatting.
275
+ */
276
+ export interface ZellijModalTheme {
277
+ /** Active palette used by this theme helper. */
278
+ palette: ZellijColorPalette;
279
+ /** Resolve color slot or explicit color into ANSI foreground/background codes. */
280
+ resolveColor: (color: PaletteColor | keyof ZellijColorPalette) => { fg: string; bg: string };
281
+ /** Apply foreground color to text. */
282
+ colorizeForeground: (color: PaletteColor | keyof ZellijColorPalette, text: string) => string;
283
+ /** Apply background color to text. */
284
+ colorizeBackground: (color: PaletteColor | keyof ZellijColorPalette, text: string) => string;
285
+ }
286
+
287
+ /**
288
+ * Resolve a `PaletteColor` into ANSI foreground/background escape codes.
289
+ */
290
+ export function resolveColor(color: PaletteColor): { fg: string; bg: string } {
291
+ if (color.type === "rgb") {
292
+ const r = clampInt(color.r, 0, 255);
293
+ const g = clampInt(color.g, 0, 255);
294
+ const b = clampInt(color.b, 0, 255);
295
+ return {
296
+ fg: `\x1b[38;2;${r};${g};${b}m`,
297
+ bg: `\x1b[48;2;${r};${g};${b}m`,
298
+ };
299
+ }
300
+
301
+ if (color.type === "8bit") {
302
+ const code = clampInt(color.code, 0, 255);
303
+ return {
304
+ fg: `\x1b[38;5;${code}m`,
305
+ bg: `\x1b[48;5;${code}m`,
306
+ };
307
+ }
308
+
309
+ const namedMap: Record<string, number> = {
310
+ black: 16,
311
+ white: 255,
312
+ red: 196,
313
+ green: 46,
314
+ blue: 45,
315
+ yellow: 226,
316
+ cyan: 51,
317
+ magenta: 201,
318
+ gray: 245,
319
+ grey: 245,
320
+ orange: 166,
321
+ };
322
+ const code = namedMap[color.name.toLowerCase()] ?? 255;
323
+ return {
324
+ fg: `\x1b[38;5;${code}m`,
325
+ bg: `\x1b[48;5;${code}m`,
326
+ };
327
+ }
328
+
329
+ /**
330
+ * Build a `ZellijModalTheme` helper from a palette.
331
+ */
332
+ export function createZellijModalTheme(palette: ZellijColorPalette): ZellijModalTheme {
333
+ return {
334
+ palette,
335
+ resolveColor: (color) => resolveColor(resolvePaletteColor(color, palette)),
336
+ colorizeForeground: (color, text) => `${resolveColor(resolvePaletteColor(color, palette)).fg}${text}${ANSI_RESET}`,
337
+ colorizeBackground: (color, text) => `${resolveColor(resolvePaletteColor(color, palette)).bg}${text}${ANSI_RESET}`,
338
+ };
339
+ }
340
+
341
+ /**
342
+ * Convert Pi `Theme` values to a Zellij modal palette.
343
+ */
344
+ export function themeToZellijPalette(theme: Theme): ZellijColorPalette {
345
+ const extract = (colorName: string, fallback: PaletteColor): PaletteColor => {
346
+ const provider = theme as unknown as {
347
+ getFgAnsi?: (name: string) => string;
348
+ };
349
+ if (!provider.getFgAnsi) {
350
+ return fallback;
351
+ }
352
+
353
+ try {
354
+ const ansi = provider.getFgAnsi(colorName);
355
+ const parsed = parseAnsiForegroundColor(ansi);
356
+ return parsed ?? fallback;
357
+ } catch {
358
+ return fallback;
359
+ }
360
+ };
361
+
362
+ return {
363
+ fg: extract("fg", DEFAULT_ZELLIJ_PALETTE.fg),
364
+ bg: extract("bg", DEFAULT_ZELLIJ_PALETTE.bg),
365
+ accent: extract("accent", DEFAULT_ZELLIJ_PALETTE.accent),
366
+ muted: extract("muted", DEFAULT_ZELLIJ_PALETTE.muted),
367
+ dim: extract("dim", DEFAULT_ZELLIJ_PALETTE.dim),
368
+ success: extract("success", DEFAULT_ZELLIJ_PALETTE.success),
369
+ error: extract("error", DEFAULT_ZELLIJ_PALETTE.error),
370
+ warning: extract("warning", DEFAULT_ZELLIJ_PALETTE.warning),
371
+ border: extract("borderMuted", DEFAULT_ZELLIJ_PALETTE.border),
372
+ borderFocused: extract("accent", DEFAULT_ZELLIJ_PALETTE.borderFocused),
373
+ borderUnfocused: extract("borderMuted", DEFAULT_ZELLIJ_PALETTE.borderUnfocused),
374
+ };
375
+ }
376
+
377
+ interface PositionedTitleSegment {
378
+ start: number;
379
+ end: number;
380
+ text: string;
381
+ color: keyof ZellijColorPalette | PaletteColor;
382
+ bold: boolean;
383
+ }
384
+
385
+ /**
386
+ * Core frame renderer for Zellij-style borders, title bar, and undertitle.
387
+ */
388
+ export class ZellijModalFrame {
389
+ private config: ZellijModalConfig;
390
+ private borders: BorderCharacters;
391
+ private theme: ZellijModalTheme;
392
+
393
+ constructor(config: ZellijModalConfig, modalTheme?: ZellijModalTheme) {
394
+ this.config = config;
395
+ this.borders = BORDER_STYLES[config.borderStyle] ?? BORDER_STYLES.rounded;
396
+ this.theme = modalTheme ?? createZellijModalTheme(config.palette);
397
+ }
398
+
399
+ /**
400
+ * Update frame configuration (used when modal config changes).
401
+ */
402
+ setConfig(config: ZellijModalConfig): void {
403
+ this.config = config;
404
+ this.borders = BORDER_STYLES[config.borderStyle] ?? BORDER_STYLES.rounded;
405
+ this.theme = createZellijModalTheme(config.palette);
406
+ }
407
+
408
+ /**
409
+ * Render one content line with left/right borders.
410
+ */
411
+ renderContentLine(content: string, width: number, palette: ZellijColorPalette): string {
412
+ const frameWidth = Math.max(2, width);
413
+ const innerWidth = Math.max(0, frameWidth - 2);
414
+ const borderColor = this.config.focused ? palette.borderFocused : palette.borderUnfocused;
415
+ const vertical = this.theme.colorizeForeground(borderColor, this.borders.vertical);
416
+ const paddedContent = truncateToWidth(content, innerWidth, "", true);
417
+ return `${vertical}${paddedContent}${vertical}`;
418
+ }
419
+
420
+ /**
421
+ * Render complete frame around provided content lines.
422
+ */
423
+ renderFrame(contentLines: string[], width: number, palette: ZellijColorPalette): ZellijModalRenderOutput {
424
+ const frameWidth = Math.max(4, width);
425
+ const safeContent = contentLines.length > 0 ? contentLines : [""];
426
+ const lines: string[] = [];
427
+
428
+ lines.push(this.renderTitleBar(frameWidth, palette));
429
+
430
+ const contentStartLine = lines.length;
431
+ for (const line of safeContent) {
432
+ lines.push(this.renderContentLine(line, frameWidth, palette));
433
+ }
434
+ const contentEndLine = lines.length - 1;
435
+
436
+ lines.push(this.renderBottomLine(frameWidth, palette));
437
+
438
+ return {
439
+ lines,
440
+ visibleWidth: frameWidth,
441
+ contentWidth: Math.max(1, frameWidth - 2 - this.config.padding * 2),
442
+ contentStartLine,
443
+ contentEndLine,
444
+ };
445
+ }
446
+
447
+ private getBorderPaint(width: number, palette: ZellijColorPalette): {
448
+ innerWidth: number;
449
+ borderPaint: (text: string) => string;
450
+ } {
451
+ const innerWidth = Math.max(0, width - 2);
452
+ const borderColor = this.config.focused ? palette.borderFocused : palette.borderUnfocused;
453
+ const borderPaint = (text: string) => this.theme.colorizeForeground(borderColor, text);
454
+ return { innerWidth, borderPaint };
455
+ }
456
+
457
+ private renderBorderedRow(
458
+ width: number,
459
+ palette: ZellijColorPalette,
460
+ corners: { left: string; right: string },
461
+ renderInner: (innerWidth: number, borderPaint: (text: string) => string) => string,
462
+ ): string {
463
+ const { innerWidth, borderPaint } = this.getBorderPaint(width, palette);
464
+ if (innerWidth === 0) {
465
+ return `${borderPaint(corners.left)}${borderPaint(corners.right)}`;
466
+ }
467
+ return `${borderPaint(corners.left)}${renderInner(innerWidth, borderPaint)}${borderPaint(corners.right)}`;
468
+ }
469
+
470
+ private renderTitleBar(width: number, palette: ZellijColorPalette): string {
471
+ return this.renderBorderedRow(width, palette, { left: this.borders.topLeft, right: this.borders.topRight }, (innerWidth, borderPaint) => {
472
+ const segments = this.positionTitleSegments(innerWidth);
473
+ let inner = "";
474
+ let cursor = 0;
475
+
476
+ for (const segment of segments) {
477
+ if (segment.start > cursor) {
478
+ inner += borderPaint(this.borders.horizontal.repeat(segment.start - cursor));
479
+ }
480
+ const text = segment.bold ? `\x1b[1m${segment.text}${ANSI_RESET}` : segment.text;
481
+ inner += this.theme.colorizeForeground(segment.color, text);
482
+ cursor = segment.end;
483
+ }
484
+
485
+ if (cursor < innerWidth) {
486
+ inner += borderPaint(this.borders.horizontal.repeat(innerWidth - cursor));
487
+ }
488
+
489
+ return inner;
490
+ });
491
+ }
492
+
493
+ private renderBottomLine(width: number, palette: ZellijColorPalette): string {
494
+ return this.renderBorderedRow(width, palette, { left: this.borders.bottomLeft, right: this.borders.bottomRight }, (innerWidth, borderPaint) => {
495
+ const helpText = this.resolveHelpText(Math.max(0, innerWidth - 3));
496
+ if (!helpText) {
497
+ return borderPaint(this.borders.horizontal.repeat(innerWidth));
498
+ }
499
+
500
+ const helpSlot = this.config.helpUndertitle?.color ?? "dim";
501
+ const safeHelp = truncateToWidth(helpText, Math.max(0, innerWidth - 3), "…");
502
+ const helpWidth = visibleWidth(safeHelp);
503
+ const rightFill = Math.max(0, innerWidth - helpWidth - 3);
504
+
505
+ return `${borderPaint(this.borders.horizontal)} ${this.theme.colorizeForeground(helpSlot, safeHelp)} ${borderPaint(this.borders.horizontal.repeat(rightFill))}`;
506
+ });
507
+ }
508
+
509
+ private positionTitleSegments(innerWidth: number): PositionedTitleSegment[] {
510
+ if (innerWidth <= 0) {
511
+ return [];
512
+ }
513
+
514
+ const left = this.resolveTitleSegment(this.config.titleBar.left, "left");
515
+ const center = this.resolveTitleSegment(this.config.titleBar.center, "center");
516
+ const right = this.resolveTitleSegment(this.config.titleBar.right, "right");
517
+
518
+ const placements: PositionedTitleSegment[] = [];
519
+
520
+ if (left) {
521
+ const leftText = this.fitTextToWidth(left.text, Math.min(innerWidth, left.maxWidth ?? innerWidth), left.truncate);
522
+ if (leftText) {
523
+ placements.push({
524
+ start: 0,
525
+ end: Math.min(innerWidth, visibleWidth(leftText)),
526
+ text: leftText,
527
+ color: left.color,
528
+ bold: left.bold ?? false,
529
+ });
530
+ }
531
+ }
532
+
533
+ if (right) {
534
+ const reservedLeft = placements[0]?.end ?? 0;
535
+ const available = Math.max(0, innerWidth - reservedLeft);
536
+ const rightText = this.fitTextToWidth(right.text, Math.min(available, right.maxWidth ?? available), right.truncate);
537
+ const rightWidth = visibleWidth(rightText);
538
+ if (rightText && rightWidth > 0) {
539
+ placements.push({
540
+ start: innerWidth - rightWidth,
541
+ end: innerWidth,
542
+ text: rightText,
543
+ color: right.color,
544
+ bold: right.bold ?? false,
545
+ });
546
+ }
547
+ }
548
+
549
+ if (center) {
550
+ const leftLimit = placements.find((placement) => placement.start === 0)?.end ?? 0;
551
+ const rightStart = placements.find((placement) => placement.end === innerWidth)?.start ?? innerWidth;
552
+ const freeWidth = Math.max(0, rightStart - leftLimit);
553
+ if (freeWidth > 0) {
554
+ const centerText = this.fitTextToWidth(center.text, Math.min(freeWidth, center.maxWidth ?? freeWidth), center.truncate);
555
+ const centerWidth = visibleWidth(centerText);
556
+ if (centerText && centerWidth > 0) {
557
+ const centeredStart = Math.floor((innerWidth - centerWidth) / 2);
558
+ const start = clampInt(centeredStart, leftLimit, Math.max(leftLimit, rightStart - centerWidth));
559
+ placements.push({
560
+ start,
561
+ end: start + centerWidth,
562
+ text: centerText,
563
+ color: center.color,
564
+ bold: center.bold ?? false,
565
+ });
566
+ }
567
+ }
568
+ }
569
+
570
+ return placements.sort((a, b) => a.start - b.start);
571
+ }
572
+
573
+ private resolveTitleSegment(
574
+ segment: TitleSegment | string | undefined,
575
+ position: "left" | "center" | "right",
576
+ ): (TitleSegment & { text: string }) | null {
577
+ if (!segment) {
578
+ return null;
579
+ }
580
+
581
+ if (typeof segment === "string") {
582
+ const color: keyof ZellijColorPalette = position === "left" ? "accent" : position === "center" ? "muted" : "dim";
583
+ return {
584
+ text: ` ${segment} `,
585
+ color,
586
+ bold: position === "left",
587
+ truncate: "end",
588
+ maxWidth: 0,
589
+ };
590
+ }
591
+
592
+ const clean = segment.text.trim();
593
+ if (!clean) {
594
+ return null;
595
+ }
596
+
597
+ return {
598
+ ...segment,
599
+ text: ` ${clean} `,
600
+ truncate: segment.truncate ?? "end",
601
+ bold: segment.bold ?? false,
602
+ };
603
+ }
604
+
605
+ private fitTextToWidth(text: string, maxWidth: number, mode: TitleSegment["truncate"]): string {
606
+ if (maxWidth <= 0) {
607
+ return "";
608
+ }
609
+ if (visibleWidth(text) <= maxWidth) {
610
+ return text;
611
+ }
612
+
613
+ switch (mode) {
614
+ case "none":
615
+ return truncateToWidth(text, maxWidth, "");
616
+ case "start":
617
+ return truncateStart(text, maxWidth);
618
+ case "middle":
619
+ return truncateMiddle(text, maxWidth);
620
+ case "end":
621
+ default:
622
+ return truncateToWidth(text, maxWidth, "…");
623
+ }
624
+ }
625
+
626
+ private resolveHelpText(maxWidth: number): string | null {
627
+ const config = this.config.helpUndertitle;
628
+ if (!config || maxWidth <= 0) {
629
+ return null;
630
+ }
631
+
632
+ if (config.textGenerator) {
633
+ try {
634
+ const generated = config.textGenerator(maxWidth);
635
+ if (generated && generated.trim()) {
636
+ return generated;
637
+ }
638
+ } catch {
639
+ return config.text?.trim() ? config.text : null;
640
+ }
641
+ }
642
+
643
+ if (config.variants && config.variants.length > 0) {
644
+ for (const variant of config.variants) {
645
+ if (visibleWidth(variant) <= maxWidth) {
646
+ return variant;
647
+ }
648
+ }
649
+ return config.variants[config.variants.length - 1] ?? null;
650
+ }
651
+
652
+ if (config.keyHints && config.keyHints.length > 0) {
653
+ const separator = config.keyHintSeparator ?? " • ";
654
+ return config.keyHints
655
+ .map((hint) => `${hint.key} ${hint.description}`)
656
+ .join(separator);
657
+ }
658
+
659
+ return config.text?.trim() ? config.text : null;
660
+ }
661
+ }
662
+
663
+ /**
664
+ * Main Zellij-style modal component wrapper.
665
+ */
666
+ export class ZellijModal implements ZellijModalComponent {
667
+ config: ZellijModalConfig;
668
+ content: ZellijModalContentRenderer;
669
+
670
+ private frame: ZellijModalFrame;
671
+ private palette: ZellijColorPalette;
672
+
673
+ constructor(content: ZellijModalContentRenderer, config: ZellijModalConfigPartial = {}, theme?: Theme) {
674
+ if (!content || typeof content.render !== "function") {
675
+ throw new Error("ZellijModal requires a valid content renderer.");
676
+ }
677
+
678
+ this.config = this.buildConfig(config);
679
+ this.palette = theme ? themeToZellijPalette(theme) : this.config.palette;
680
+ this.content = content;
681
+ this.frame = new ZellijModalFrame({ ...this.config, palette: this.palette });
682
+ }
683
+
684
+ /**
685
+ * Render content only (without frame).
686
+ */
687
+ render(width: number): string[] {
688
+ const contentWidth = Math.max(1, width - 2 - this.config.padding * 2);
689
+ const paddedWidth = contentWidth + this.config.padding * 2;
690
+ const sidePadding = " ".repeat(this.config.padding);
691
+ const lines: string[] = [];
692
+
693
+ try {
694
+ const rawLines = this.content.render(contentWidth);
695
+ const normalized = rawLines.length > 0 ? rawLines : [""];
696
+
697
+ pushPaddingLines(lines, this.config.padding, paddedWidth);
698
+
699
+ for (const line of normalized) {
700
+ const fitted = truncateToWidth(line, contentWidth, "", true);
701
+ lines.push(`${sidePadding}${fitted}${sidePadding}`);
702
+ }
703
+
704
+ pushPaddingLines(lines, this.config.padding, paddedWidth);
705
+ } catch (error) {
706
+ const message = error instanceof Error ? error.message : String(error);
707
+ const safe = truncateToWidth(` Render error: ${message} `, paddedWidth, "…", true);
708
+ lines.push(safe);
709
+ }
710
+
711
+ return lines.length > 0 ? lines : [" ".repeat(paddedWidth)];
712
+ }
713
+
714
+ /**
715
+ * Render complete frame + content.
716
+ */
717
+ renderModal(width: number): ZellijModalRenderOutput {
718
+ const frameWidth = this.resolveModalWidth(width);
719
+ const contentLines = this.render(frameWidth);
720
+ return this.frame.renderFrame(contentLines, frameWidth, this.palette);
721
+ }
722
+
723
+ /**
724
+ * Invalidate child renderer state.
725
+ */
726
+ invalidate(): void {
727
+ this.content.invalidate();
728
+ }
729
+
730
+ /**
731
+ * Delegate input to child renderer.
732
+ */
733
+ handleInput(data: string): void {
734
+ this.content.handleInput?.(data);
735
+ }
736
+
737
+ /**
738
+ * Get overlay options for `ctx.ui.custom()`.
739
+ */
740
+ getOverlayOptions(): { overlay: true; overlayOptions: ZellijModalConfig["overlay"] } {
741
+ return {
742
+ overlay: true,
743
+ overlayOptions: this.config.overlay,
744
+ };
745
+ }
746
+
747
+ /**
748
+ * Dispose modal resources.
749
+ */
750
+ dispose(): void {
751
+ this.content.invalidate();
752
+ }
753
+
754
+ private buildConfig(partial: ZellijModalConfigPartial): ZellijModalConfig {
755
+ const borderStyle = partial.borderStyle && BORDER_STYLES[partial.borderStyle] ? partial.borderStyle : "rounded";
756
+ const padding = Math.max(0, partial.padding ?? 1);
757
+ const minWidth = Math.max(4, partial.minWidth ?? 40);
758
+ const maxWidth = Math.max(0, partial.maxWidth ?? 0);
759
+ const helpUndertitle = normalizeHelpUndertitle(partial.helpText, partial.helpUndertitle);
760
+
761
+ return {
762
+ borderStyle,
763
+ palette: partial.palette ?? DEFAULT_ZELLIJ_PALETTE,
764
+ focused: partial.focused ?? true,
765
+ padding,
766
+ titleBar: partial.titleBar ?? { left: partial.title ?? "Modal" },
767
+ helpUndertitle,
768
+ minWidth,
769
+ maxWidth,
770
+ overlay: {
771
+ anchor: partial.overlay?.anchor ?? "center",
772
+ width: partial.overlay?.width ?? 70,
773
+ maxHeight: partial.overlay?.maxHeight ?? "80%",
774
+ margin: Math.max(0, partial.overlay?.margin ?? 1),
775
+ },
776
+ };
777
+ }
778
+
779
+ private resolveModalWidth(availableWidth: number): number {
780
+ const width = Math.max(4, availableWidth);
781
+ const boundedMax = this.config.maxWidth > 0 ? Math.min(width, this.config.maxWidth) : width;
782
+ if (boundedMax >= this.config.minWidth) {
783
+ return boundedMax;
784
+ }
785
+ return Math.max(4, boundedMax);
786
+ }
787
+ }
788
+
789
+ /**
790
+ * Options for the pre-built settings modal content renderer.
791
+ */
792
+ export interface SettingsModalOptions {
793
+ /** Modal heading. */
794
+ title: string;
795
+ /** Optional descriptive subtitle shown above settings. */
796
+ description?: string;
797
+ /** Settings list items. */
798
+ settings: SettingItem[];
799
+ /** Called when a setting value changes. */
800
+ onChange: (id: string, value: string) => void;
801
+ /** Called when modal should close. */
802
+ onClose: () => void;
803
+ /** Optional help text shown below settings. */
804
+ helpText?: string;
805
+ /** Enables in-list search (`/` and typing behavior from SettingsList). */
806
+ enableSearch?: boolean;
807
+ }
808
+
809
+ /**
810
+ * Pre-built Zellij content renderer for configuration modals.
811
+ */
812
+ export class ZellijSettingsModal implements ZellijModalContentRenderer {
813
+ private container: Container;
814
+ private contentBox: Box;
815
+ private settingsList: SettingsList;
816
+ private options: SettingsModalOptions;
817
+ private theme: Theme;
818
+
819
+ constructor(options: SettingsModalOptions, theme: Theme) {
820
+ if (!options.title || !options.title.trim()) {
821
+ throw new Error("ZellijSettingsModal requires a non-empty title.");
822
+ }
823
+
824
+ this.options = options;
825
+ this.theme = theme;
826
+ this.container = new Container();
827
+ this.contentBox = new Box(0, 0);
828
+
829
+ this.contentBox.addChild(new Text(this.theme.fg("accent", this.theme.bold(options.title)), 0, 0));
830
+
831
+ if (options.description) {
832
+ this.contentBox.addChild(new Spacer(1));
833
+ this.contentBox.addChild(new Text(this.theme.fg("muted", options.description), 0, 0));
834
+ }
835
+
836
+ this.contentBox.addChild(new Spacer(1));
837
+ this.settingsList = new SettingsList(
838
+ options.settings,
839
+ Math.min(Math.max(options.settings.length + 2, 6), 18),
840
+ getSettingsListTheme(),
841
+ (id, value) => {
842
+ this.options.onChange(id, value);
843
+ },
844
+ () => {
845
+ this.options.onClose();
846
+ },
847
+ { enableSearch: options.enableSearch ?? true },
848
+ );
849
+ this.contentBox.addChild(this.settingsList);
850
+
851
+ if (options.helpText) {
852
+ this.contentBox.addChild(new Spacer(1));
853
+ this.contentBox.addChild(new Text(this.theme.fg("dim", options.helpText), 0, 0));
854
+ }
855
+
856
+ this.container.addChild(this.contentBox);
857
+ }
858
+
859
+ /**
860
+ * Render settings modal content.
861
+ */
862
+ render(width: number): string[] {
863
+ const safeWidth = Math.max(1, width);
864
+ try {
865
+ return this.container.render(safeWidth);
866
+ } catch (error) {
867
+ const message = error instanceof Error ? error.message : String(error);
868
+ return [this.theme.fg("error", truncateToWidth(`Settings render error: ${message}`, safeWidth, "…"))];
869
+ }
870
+ }
871
+
872
+ /**
873
+ * Invalidate internal caches.
874
+ */
875
+ invalidate(): void {
876
+ this.container.invalidate();
877
+ }
878
+
879
+ /**
880
+ * Forward key input to SettingsList.
881
+ */
882
+ handleInput(data: string): void {
883
+ if (isEnterActivationInput(data)) {
884
+ return;
885
+ }
886
+ this.settingsList.handleInput(data);
887
+ }
888
+
889
+ /**
890
+ * Programmatically update one setting value in the list.
891
+ */
892
+ updateValue(id: string, value: string): void {
893
+ this.settingsList.updateValue(id, value);
894
+ }
895
+ }
896
+
897
+ function pushPaddingLines(lines: string[], count: number, paddedWidth: number): void {
898
+ for (let i = 0; i < count; i++) {
899
+ lines.push(" ".repeat(paddedWidth));
900
+ }
901
+ }
902
+
903
+ function isEnterActivationInput(data: string): boolean {
904
+ return data === "\r" || data === "\n" || data === "\r\n";
905
+ }
906
+
907
+ function normalizeHelpUndertitle(
908
+ helpText: ZellijModalConfigPartial["helpText"],
909
+ helpUndertitle: HelpUndertitleConfig | undefined,
910
+ ): HelpUndertitleConfig | undefined {
911
+ if (helpUndertitle) {
912
+ return helpUndertitle;
913
+ }
914
+ if (typeof helpText === "string") {
915
+ return helpText ? { text: helpText } : undefined;
916
+ }
917
+ return helpText;
918
+ }
919
+
920
+ function resolvePaletteColor(color: PaletteColor | keyof ZellijColorPalette, palette: ZellijColorPalette): PaletteColor {
921
+ if (typeof color === "string") {
922
+ return palette[color];
923
+ }
924
+ return color;
925
+ }
926
+
927
+ function parseAnsiForegroundColor(ansi: string): PaletteColor | null {
928
+ const rgbMatch = /\x1b\[38;2;(\d+);(\d+);(\d+)m/.exec(ansi);
929
+ if (rgbMatch) {
930
+ const [, r, g, b] = rgbMatch;
931
+ return {
932
+ type: "rgb",
933
+ r: clampInt(Number.parseInt(r ?? "0", 10), 0, 255),
934
+ g: clampInt(Number.parseInt(g ?? "0", 10), 0, 255),
935
+ b: clampInt(Number.parseInt(b ?? "0", 10), 0, 255),
936
+ };
937
+ }
938
+
939
+ const bit8Match = /\x1b\[38;5;(\d+)m/.exec(ansi);
940
+ if (bit8Match) {
941
+ const [, code] = bit8Match;
942
+ return {
943
+ type: "8bit",
944
+ code: clampInt(Number.parseInt(code ?? "255", 10), 0, 255),
945
+ };
946
+ }
947
+
948
+ return null;
949
+ }
950
+
951
+ function earlyTruncate(text: string, maxWidth: number): string | undefined {
952
+ if (visibleWidth(text) <= maxWidth) {
953
+ return text;
954
+ }
955
+ if (maxWidth <= 1) {
956
+ return "…".slice(0, maxWidth);
957
+ }
958
+ return undefined;
959
+ }
960
+
961
+ function withEarlyTruncation(
962
+ text: string,
963
+ maxWidth: number,
964
+ compute: () => string,
965
+ ): string {
966
+ const early = earlyTruncate(text, maxWidth);
967
+ if (early !== undefined) {
968
+ return early;
969
+ }
970
+ return compute();
971
+ }
972
+
973
+ function truncateStart(text: string, maxWidth: number): string {
974
+ return withEarlyTruncation(text, maxWidth, () => {
975
+ const chars = Array.from(text);
976
+ let current = "";
977
+ for (let index = chars.length - 1; index >= 0; index--) {
978
+ const candidate = `${chars[index]}${current}`;
979
+ if (visibleWidth(candidate) >= maxWidth - 1) {
980
+ current = candidate;
981
+ break;
982
+ }
983
+ current = candidate;
984
+ }
985
+ return `…${truncateToWidth(current, Math.max(0, maxWidth - 1), "")}`;
986
+ });
987
+ }
988
+
989
+ function truncateMiddle(text: string, maxWidth: number): string {
990
+ return withEarlyTruncation(text, maxWidth, () => {
991
+ const headTarget = Math.floor((maxWidth - 1) / 2);
992
+ const tailTarget = Math.max(0, maxWidth - 1 - headTarget);
993
+ const head = truncateToWidth(text, headTarget, "");
994
+
995
+ const chars = Array.from(text);
996
+ let tail = "";
997
+ for (let index = chars.length - 1; index >= 0; index--) {
998
+ const candidate = `${chars[index]}${tail}`;
999
+ if (visibleWidth(candidate) > tailTarget) {
1000
+ continue;
1001
+ }
1002
+ tail = candidate;
1003
+ if (visibleWidth(tail) === tailTarget) {
1004
+ break;
1005
+ }
1006
+ }
1007
+
1008
+ return `${head}…${tail}`;
1009
+ });
1010
+ }
1011
+
1012
+ function clampInt(value: number, min: number, max: number): number {
1013
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
1014
+ return min;
1015
+ }
1016
+ return Math.min(max, Math.max(min, Math.round(value)));
1017
+ }
1018
+
1019
+ /**
1020
+ * Extension factory entrypoint for Pi extension loader.
1021
+ *
1022
+ * This extension intentionally registers no commands/events and only exposes
1023
+ * reusable modal primitives for sibling extensions.
1024
+ */
1025
+ export default function zellijModalExtension(_pi: ExtensionAPI): void {
1026
+ // no-op
1027
+ }