@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
@@ -1,436 +1,436 @@
1
- /**
2
- * Preset Extension
3
- *
4
- * Allows defining named presets that configure model, thinking level, tools,
5
- * and system prompt instructions. Presets are defined in JSON config files
6
- * and can be activated via CLI flag, /preset command, or Ctrl+Shift+U to cycle.
7
- *
8
- * Config files (merged, project takes precedence):
9
- * - ~/.pi/agent/presets.json (global)
10
- * - <cwd>/.pi/presets.json (project-local)
11
- *
12
- * Example presets.json:
13
- * ```json
14
- * {
15
- * "plan": {
16
- * "provider": "openai-codex",
17
- * "model": "gpt-5.2-codex",
18
- * "thinkingLevel": "high",
19
- * "tools": ["read", "grep", "find", "ls"],
20
- * "instructions": "You are in PLANNING MODE. Your job is to deeply understand the problem and create a detailed implementation plan.\n\nRules:\n- DO NOT make any changes. You cannot edit or write files.\n- Read files IN FULL (no offset/limit) to get complete context. Partial reads miss critical details.\n- Explore thoroughly: grep for related code, find similar patterns, understand the architecture.\n- Ask clarifying questions if requirements are ambiguous. Do not assume.\n- Identify risks, edge cases, and dependencies before proposing solutions.\n\nOutput:\n- Create a structured plan with numbered steps.\n- For each step: what to change, why, and potential risks.\n- List files that will be modified.\n- Note any tests that should be added or updated.\n\nWhen done, ask the user if they want you to:\n1. Write the plan to a markdown file (e.g., PLAN.md)\n2. Create a GitHub issue with the plan\n3. Proceed to implementation (they should switch to 'implement' preset)"
21
- * },
22
- * "implement": {
23
- * "provider": "anthropic",
24
- * "model": "claude-sonnet-4-5",
25
- * "thinkingLevel": "high",
26
- * "tools": ["read", "bash", "edit", "write"],
27
- * "instructions": "You are in IMPLEMENTATION MODE. Your job is to make focused, correct changes.\n\nRules:\n- Keep scope tight. Do exactly what was asked, no more.\n- Read files before editing to understand current state.\n- Make surgical edits. Prefer edit over write for existing files.\n- Explain your reasoning briefly before each change.\n- Run tests or type checks after changes if the project has them (npm test, npm run check, etc.).\n- If you encounter unexpected complexity, STOP and explain the issue rather than hacking around it.\n\nIf no plan exists:\n- Ask clarifying questions before starting.\n- Propose what you'll do and get confirmation for non-trivial changes.\n\nAfter completing changes:\n- Summarize what was done.\n- Note any follow-up work or tests that should be added."
28
- * }
29
- * }
30
- * ```
31
- *
32
- * Usage:
33
- * - `pi --preset plan` - start with plan preset
34
- * - `/preset` - show selector to switch presets mid-session
35
- * - `/preset implement` - switch to implement preset directly
36
- * - `Ctrl+Shift+U` - cycle through presets
37
- *
38
- * CLI flags always override preset values.
39
- */
40
-
41
- import { existsSync, readFileSync } from "node:fs";
42
- import { join } from "node:path";
43
- import type { Api, Model } from "@earendil-works/pi-ai";
44
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
45
- import { CONFIG_DIR_NAME, DynamicBorder, getAgentDir } from "@earendil-works/pi-coding-agent";
46
- import { Container, Key, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
47
-
48
- // Preset configuration
49
- interface Preset {
50
- /** Provider name (e.g., "anthropic", "openai") */
51
- provider?: string;
52
- /** Model ID (e.g., "claude-sonnet-4-5") */
53
- model?: string;
54
- /** Thinking level */
55
- thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
56
- /** Tools to enable (replaces default set) */
57
- tools?: string[];
58
- /** Instructions to append to system prompt */
59
- instructions?: string;
60
- }
61
-
62
- interface PresetsConfig {
63
- [name: string]: Preset;
64
- }
65
-
66
- /**
67
- * Load presets from config files.
68
- * Project-local presets override global presets with the same name.
69
- */
70
- function loadPresets(cwd: string): PresetsConfig {
71
- const globalPath = join(getAgentDir(), "presets.json");
72
- const projectPath = join(cwd, CONFIG_DIR_NAME, "presets.json");
73
-
74
- let globalPresets: PresetsConfig = {};
75
- let projectPresets: PresetsConfig = {};
76
-
77
- // Load global presets
78
- if (existsSync(globalPath)) {
79
- try {
80
- const content = readFileSync(globalPath, "utf-8");
81
- globalPresets = JSON.parse(content);
82
- } catch (err) {
83
- console.error(`Failed to load global presets from ${globalPath}: ${err}`);
84
- }
85
- }
86
-
87
- // Load project presets
88
- if (existsSync(projectPath)) {
89
- try {
90
- const content = readFileSync(projectPath, "utf-8");
91
- projectPresets = JSON.parse(content);
92
- } catch (err) {
93
- console.error(`Failed to load project presets from ${projectPath}: ${err}`);
94
- }
95
- }
96
-
97
- // Merge (project overrides global)
98
- return { ...globalPresets, ...projectPresets };
99
- }
100
-
101
- interface OriginalState {
102
- model: Model<Api> | undefined;
103
- thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
104
- tools: string[];
105
- }
106
-
107
- export default function presetExtension(pi: ExtensionAPI) {
108
- let presets: PresetsConfig = {};
109
- let activePresetName: string | undefined;
110
- let activePreset: Preset | undefined;
111
- let originalState: OriginalState | undefined;
112
-
113
- // Register --preset CLI flag
114
- pi.registerFlag("preset", {
115
- description: "Preset configuration to use",
116
- type: "string",
117
- });
118
-
119
- /**
120
- * Apply a preset configuration.
121
- */
122
- async function applyPreset(name: string, preset: Preset, ctx: ExtensionContext): Promise<boolean> {
123
- // Snapshot state before the first preset is applied (i.e. only when transitioning from no-preset)
124
- if (activePresetName === undefined) {
125
- originalState = {
126
- model: ctx.model,
127
- thinkingLevel: pi.getThinkingLevel(),
128
- tools: pi.getActiveTools(),
129
- };
130
- }
131
-
132
- // Apply model if specified
133
- if (preset.provider && preset.model) {
134
- const model = ctx.modelRegistry.find(preset.provider, preset.model);
135
- if (model) {
136
- const success = await pi.setModel(model);
137
- if (!success) {
138
- ctx.ui.notify(`Preset "${name}": No API key for ${preset.provider}/${preset.model}`, "warning");
139
- }
140
- } else {
141
- ctx.ui.notify(`Preset "${name}": Model ${preset.provider}/${preset.model} not found`, "warning");
142
- }
143
- }
144
-
145
- // Apply thinking level if specified
146
- if (preset.thinkingLevel) {
147
- pi.setThinkingLevel(preset.thinkingLevel);
148
- }
149
-
150
- // Apply tools if specified
151
- if (preset.tools && preset.tools.length > 0) {
152
- const allToolNames = pi.getAllTools().map((t) => t.name);
153
- const validTools = preset.tools.filter((t) => allToolNames.includes(t));
154
- const invalidTools = preset.tools.filter((t) => !allToolNames.includes(t));
155
-
156
- if (invalidTools.length > 0) {
157
- ctx.ui.notify(`Preset "${name}": Unknown tools: ${invalidTools.join(", ")}`, "warning");
158
- }
159
-
160
- if (validTools.length > 0) {
161
- pi.setActiveTools(validTools);
162
- }
163
- }
164
-
165
- // Store active preset for system prompt injection
166
- activePresetName = name;
167
- activePreset = preset;
168
-
169
- return true;
170
- }
171
-
172
- /**
173
- * Build description string for a preset.
174
- */
175
- function buildPresetDescription(preset: Preset): string {
176
- const parts: string[] = [];
177
-
178
- if (preset.provider && preset.model) {
179
- parts.push(`${preset.provider}/${preset.model}`);
180
- }
181
- if (preset.thinkingLevel) {
182
- parts.push(`thinking:${preset.thinkingLevel}`);
183
- }
184
- if (preset.tools) {
185
- parts.push(`tools:${preset.tools.join(",")}`);
186
- }
187
- if (preset.instructions) {
188
- const truncated =
189
- preset.instructions.length > 30 ? `${preset.instructions.slice(0, 27)}...` : preset.instructions;
190
- parts.push(`"${truncated}"`);
191
- }
192
-
193
- return parts.join(" | ");
194
- }
195
-
196
- /**
197
- * Show preset selector UI using custom SelectList component.
198
- */
199
- async function showPresetSelector(ctx: ExtensionContext): Promise<void> {
200
- const presetNames = Object.keys(presets);
201
-
202
- if (presetNames.length === 0) {
203
- ctx.ui.notify(
204
- `No presets defined. Add presets to ${join(getAgentDir(), "presets.json")} or ${join(ctx.cwd, CONFIG_DIR_NAME, "presets.json")}`,
205
- "warning",
206
- );
207
- return;
208
- }
209
-
210
- // Build select items with descriptions
211
- const items: SelectItem[] = presetNames.map((name) => {
212
- const preset = presets[name];
213
- const isActive = name === activePresetName;
214
- return {
215
- value: name,
216
- label: isActive ? `${name} (active)` : name,
217
- description: buildPresetDescription(preset),
218
- };
219
- });
220
-
221
- // Add "None" option to clear preset
222
- items.push({
223
- value: "(none)",
224
- label: "(none)",
225
- description: "Clear active preset, restore defaults",
226
- });
227
-
228
- const result = await ctx.ui.custom<string | null>((tui, theme, _kb, done) => {
229
- const container = new Container();
230
- container.addChild(new DynamicBorder((str) => theme.fg("accent", str)));
231
-
232
- // Header
233
- container.addChild(new Text(theme.fg("accent", theme.bold("Select Preset"))));
234
-
235
- // SelectList with themed styling
236
- const selectList = new SelectList(items, Math.min(items.length, 10), {
237
- selectedPrefix: (text) => theme.fg("accent", text),
238
- selectedText: (text) => theme.fg("accent", text),
239
- description: (text) => theme.fg("muted", text),
240
- scrollInfo: (text) => theme.fg("dim", text),
241
- noMatch: (text) => theme.fg("warning", text),
242
- });
243
-
244
- selectList.onSelect = (item) => done(item.value);
245
- selectList.onCancel = () => done(null);
246
-
247
- container.addChild(selectList);
248
-
249
- // Footer hint
250
- container.addChild(new Text(theme.fg("dim", "↑↓ navigate • enter select • esc cancel")));
251
-
252
- container.addChild(new DynamicBorder((str) => theme.fg("accent", str)));
253
-
254
- return {
255
- render(width: number) {
256
- return container.render(width);
257
- },
258
- invalidate() {
259
- container.invalidate();
260
- },
261
- handleInput(data: string) {
262
- selectList.handleInput(data);
263
- tui.requestRender();
264
- },
265
- };
266
- });
267
-
268
- if (!result) return;
269
-
270
- if (result === "(none)") {
271
- // Clear preset and restore original state
272
- activePresetName = undefined;
273
- activePreset = undefined;
274
- if (originalState) {
275
- if (originalState.model) {
276
- await pi.setModel(originalState.model);
277
- }
278
- pi.setThinkingLevel(originalState.thinkingLevel);
279
- pi.setActiveTools(originalState.tools);
280
- } else {
281
- pi.setActiveTools(["read", "bash", "edit", "write"]);
282
- }
283
- ctx.ui.notify("Preset cleared, defaults restored", "info");
284
- updateStatus(ctx);
285
- return;
286
- }
287
-
288
- const preset = presets[result];
289
- if (preset) {
290
- await applyPreset(result, preset, ctx);
291
- ctx.ui.notify(`Preset "${result}" activated`, "info");
292
- updateStatus(ctx);
293
- }
294
- }
295
-
296
- /**
297
- * Update status indicator.
298
- */
299
- function updateStatus(ctx: ExtensionContext) {
300
- if (activePresetName) {
301
- ctx.ui.setStatus("preset", ctx.ui.theme.fg("accent", `preset:${activePresetName}`));
302
- } else {
303
- ctx.ui.setStatus("preset", undefined);
304
- }
305
- }
306
-
307
- function getPresetOrder(): string[] {
308
- return Object.keys(presets).sort();
309
- }
310
-
311
- async function cyclePreset(ctx: ExtensionContext): Promise<void> {
312
- const presetNames = getPresetOrder();
313
- if (presetNames.length === 0) {
314
- ctx.ui.notify(
315
- `No presets defined. Add presets to ${join(getAgentDir(), "presets.json")} or ${join(ctx.cwd, CONFIG_DIR_NAME, "presets.json")}`,
316
- "warning",
317
- );
318
- return;
319
- }
320
-
321
- const cycleList = ["(none)", ...presetNames];
322
- const currentName = activePresetName ?? "(none)";
323
- const currentIndex = cycleList.indexOf(currentName);
324
- const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % cycleList.length;
325
- const nextName = cycleList[nextIndex];
326
-
327
- if (nextName === "(none)") {
328
- activePresetName = undefined;
329
- activePreset = undefined;
330
- if (originalState) {
331
- if (originalState.model) {
332
- await pi.setModel(originalState.model);
333
- }
334
- pi.setThinkingLevel(originalState.thinkingLevel);
335
- pi.setActiveTools(originalState.tools);
336
- } else {
337
- pi.setActiveTools(["read", "bash", "edit", "write"]);
338
- }
339
- ctx.ui.notify("Preset cleared, defaults restored", "info");
340
- updateStatus(ctx);
341
- return;
342
- }
343
-
344
- const preset = presets[nextName];
345
- if (!preset) return;
346
-
347
- await applyPreset(nextName, preset, ctx);
348
- ctx.ui.notify(`Preset "${nextName}" activated`, "info");
349
- updateStatus(ctx);
350
- }
351
-
352
- pi.registerShortcut(Key.ctrlShift("u"), {
353
- description: "Cycle presets",
354
- handler: async (ctx) => {
355
- await cyclePreset(ctx);
356
- },
357
- });
358
-
359
- // Register /preset command
360
- pi.registerCommand("preset", {
361
- description: "Switch preset configuration",
362
- handler: async (args, ctx) => {
363
- // If preset name provided, apply directly
364
- if (args?.trim()) {
365
- const name = args.trim();
366
- const preset = presets[name];
367
-
368
- if (!preset) {
369
- const available = Object.keys(presets).join(", ") || "(none defined)";
370
- ctx.ui.notify(`Unknown preset "${name}". Available: ${available}`, "error");
371
- return;
372
- }
373
-
374
- await applyPreset(name, preset, ctx);
375
- ctx.ui.notify(`Preset "${name}" activated`, "info");
376
- updateStatus(ctx);
377
- return;
378
- }
379
-
380
- // Otherwise show selector
381
- await showPresetSelector(ctx);
382
- },
383
- });
384
-
385
- // Inject preset instructions into system prompt
386
- pi.on("before_agent_start", async (event) => {
387
- if (activePreset?.instructions) {
388
- return {
389
- systemPrompt: `${event.systemPrompt}\n\n${activePreset.instructions}`,
390
- };
391
- }
392
- });
393
-
394
- // Initialize on session start
395
- pi.on("session_start", async (_event, ctx) => {
396
- // Load presets from config files
397
- presets = loadPresets(ctx.cwd);
398
-
399
- // Check for --preset flag
400
- const presetFlag = pi.getFlag("preset");
401
- if (typeof presetFlag === "string" && presetFlag) {
402
- const preset = presets[presetFlag];
403
- if (preset) {
404
- await applyPreset(presetFlag, preset, ctx);
405
- ctx.ui.notify(`Preset "${presetFlag}" activated`, "info");
406
- } else {
407
- const available = Object.keys(presets).join(", ") || "(none defined)";
408
- ctx.ui.notify(`Unknown preset "${presetFlag}". Available: ${available}`, "warning");
409
- }
410
- }
411
-
412
- // Restore preset from session state
413
- const entries = ctx.sessionManager.getEntries();
414
- const presetEntry = entries
415
- .filter((e: { type: string; customType?: string }) => e.type === "custom" && e.customType === "preset-state")
416
- .pop() as { data?: { name: string } } | undefined;
417
-
418
- if (presetEntry?.data?.name && !presetFlag) {
419
- const preset = presets[presetEntry.data.name];
420
- if (preset) {
421
- activePresetName = presetEntry.data.name;
422
- activePreset = preset;
423
- // Don't re-apply model/tools on restore, just keep the name for instructions
424
- }
425
- }
426
-
427
- updateStatus(ctx);
428
- });
429
-
430
- // Persist preset state
431
- pi.on("turn_start", async () => {
432
- if (activePresetName) {
433
- pi.appendEntry("preset-state", { name: activePresetName });
434
- }
435
- });
436
- }
1
+ /**
2
+ * Preset Extension
3
+ *
4
+ * Allows defining named presets that configure model, thinking level, tools,
5
+ * and system prompt instructions. Presets are defined in JSON config files
6
+ * and can be activated via CLI flag, /preset command, or Ctrl+Shift+U to cycle.
7
+ *
8
+ * Config files (merged, project takes precedence):
9
+ * - ~/.pi/agent/presets.json (global)
10
+ * - <cwd>/.pi/presets.json (project-local)
11
+ *
12
+ * Example presets.json:
13
+ * ```json
14
+ * {
15
+ * "plan": {
16
+ * "provider": "openai-codex",
17
+ * "model": "gpt-5.2-codex",
18
+ * "thinkingLevel": "high",
19
+ * "tools": ["read", "grep", "find", "ls"],
20
+ * "instructions": "You are in PLANNING MODE. Your job is to deeply understand the problem and create a detailed implementation plan.\n\nRules:\n- DO NOT make any changes. You cannot edit or write files.\n- Read files IN FULL (no offset/limit) to get complete context. Partial reads miss critical details.\n- Explore thoroughly: grep for related code, find similar patterns, understand the architecture.\n- Ask clarifying questions if requirements are ambiguous. Do not assume.\n- Identify risks, edge cases, and dependencies before proposing solutions.\n\nOutput:\n- Create a structured plan with numbered steps.\n- For each step: what to change, why, and potential risks.\n- List files that will be modified.\n- Note any tests that should be added or updated.\n\nWhen done, ask the user if they want you to:\n1. Write the plan to a markdown file (e.g., PLAN.md)\n2. Create a GitHub issue with the plan\n3. Proceed to implementation (they should switch to 'implement' preset)"
21
+ * },
22
+ * "implement": {
23
+ * "provider": "anthropic",
24
+ * "model": "claude-sonnet-4-5",
25
+ * "thinkingLevel": "high",
26
+ * "tools": ["read", "bash", "edit", "write"],
27
+ * "instructions": "You are in IMPLEMENTATION MODE. Your job is to make focused, correct changes.\n\nRules:\n- Keep scope tight. Do exactly what was asked, no more.\n- Read files before editing to understand current state.\n- Make surgical edits. Prefer edit over write for existing files.\n- Explain your reasoning briefly before each change.\n- Run tests or type checks after changes if the project has them (npm test, npm run check, etc.).\n- If you encounter unexpected complexity, STOP and explain the issue rather than hacking around it.\n\nIf no plan exists:\n- Ask clarifying questions before starting.\n- Propose what you'll do and get confirmation for non-trivial changes.\n\nAfter completing changes:\n- Summarize what was done.\n- Note any follow-up work or tests that should be added."
28
+ * }
29
+ * }
30
+ * ```
31
+ *
32
+ * Usage:
33
+ * - `pi --preset plan` - start with plan preset
34
+ * - `/preset` - show selector to switch presets mid-session
35
+ * - `/preset implement` - switch to implement preset directly
36
+ * - `Ctrl+Shift+U` - cycle through presets
37
+ *
38
+ * CLI flags always override preset values.
39
+ */
40
+
41
+ import { existsSync, readFileSync } from "node:fs";
42
+ import { join } from "node:path";
43
+ import type { Api, Model } from "@earendil-works/pi-ai";
44
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
45
+ import { CONFIG_DIR_NAME, DynamicBorder, getAgentDir } from "@earendil-works/pi-coding-agent";
46
+ import { Container, Key, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
47
+
48
+ // Preset configuration
49
+ interface Preset {
50
+ /** Provider name (e.g., "anthropic", "openai") */
51
+ provider?: string;
52
+ /** Model ID (e.g., "claude-sonnet-4-5") */
53
+ model?: string;
54
+ /** Thinking level */
55
+ thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
56
+ /** Tools to enable (replaces default set) */
57
+ tools?: string[];
58
+ /** Instructions to append to system prompt */
59
+ instructions?: string;
60
+ }
61
+
62
+ interface PresetsConfig {
63
+ [name: string]: Preset;
64
+ }
65
+
66
+ /**
67
+ * Load presets from config files.
68
+ * Project-local presets override global presets with the same name.
69
+ */
70
+ function loadPresets(cwd: string): PresetsConfig {
71
+ const globalPath = join(getAgentDir(), "presets.json");
72
+ const projectPath = join(cwd, CONFIG_DIR_NAME, "presets.json");
73
+
74
+ let globalPresets: PresetsConfig = {};
75
+ let projectPresets: PresetsConfig = {};
76
+
77
+ // Load global presets
78
+ if (existsSync(globalPath)) {
79
+ try {
80
+ const content = readFileSync(globalPath, "utf-8");
81
+ globalPresets = JSON.parse(content);
82
+ } catch (err) {
83
+ console.error(`Failed to load global presets from ${globalPath}: ${err}`);
84
+ }
85
+ }
86
+
87
+ // Load project presets
88
+ if (existsSync(projectPath)) {
89
+ try {
90
+ const content = readFileSync(projectPath, "utf-8");
91
+ projectPresets = JSON.parse(content);
92
+ } catch (err) {
93
+ console.error(`Failed to load project presets from ${projectPath}: ${err}`);
94
+ }
95
+ }
96
+
97
+ // Merge (project overrides global)
98
+ return { ...globalPresets, ...projectPresets };
99
+ }
100
+
101
+ interface OriginalState {
102
+ model: Model<Api> | undefined;
103
+ thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
104
+ tools: string[];
105
+ }
106
+
107
+ export default function presetExtension(pi: ExtensionAPI) {
108
+ let presets: PresetsConfig = {};
109
+ let activePresetName: string | undefined;
110
+ let activePreset: Preset | undefined;
111
+ let originalState: OriginalState | undefined;
112
+
113
+ // Register --preset CLI flag
114
+ pi.registerFlag("preset", {
115
+ description: "Preset configuration to use",
116
+ type: "string",
117
+ });
118
+
119
+ /**
120
+ * Apply a preset configuration.
121
+ */
122
+ async function applyPreset(name: string, preset: Preset, ctx: ExtensionContext): Promise<boolean> {
123
+ // Snapshot state before the first preset is applied (i.e. only when transitioning from no-preset)
124
+ if (activePresetName === undefined) {
125
+ originalState = {
126
+ model: ctx.model,
127
+ thinkingLevel: pi.getThinkingLevel(),
128
+ tools: pi.getActiveTools(),
129
+ };
130
+ }
131
+
132
+ // Apply model if specified
133
+ if (preset.provider && preset.model) {
134
+ const model = ctx.modelRegistry.find(preset.provider, preset.model);
135
+ if (model) {
136
+ const success = await pi.setModel(model);
137
+ if (!success) {
138
+ ctx.ui.notify(`Preset "${name}": No API key for ${preset.provider}/${preset.model}`, "warning");
139
+ }
140
+ } else {
141
+ ctx.ui.notify(`Preset "${name}": Model ${preset.provider}/${preset.model} not found`, "warning");
142
+ }
143
+ }
144
+
145
+ // Apply thinking level if specified
146
+ if (preset.thinkingLevel) {
147
+ pi.setThinkingLevel(preset.thinkingLevel);
148
+ }
149
+
150
+ // Apply tools if specified
151
+ if (preset.tools && preset.tools.length > 0) {
152
+ const allToolNames = pi.getAllTools().map((t) => t.name);
153
+ const validTools = preset.tools.filter((t) => allToolNames.includes(t));
154
+ const invalidTools = preset.tools.filter((t) => !allToolNames.includes(t));
155
+
156
+ if (invalidTools.length > 0) {
157
+ ctx.ui.notify(`Preset "${name}": Unknown tools: ${invalidTools.join(", ")}`, "warning");
158
+ }
159
+
160
+ if (validTools.length > 0) {
161
+ pi.setActiveTools(validTools);
162
+ }
163
+ }
164
+
165
+ // Store active preset for system prompt injection
166
+ activePresetName = name;
167
+ activePreset = preset;
168
+
169
+ return true;
170
+ }
171
+
172
+ /**
173
+ * Build description string for a preset.
174
+ */
175
+ function buildPresetDescription(preset: Preset): string {
176
+ const parts: string[] = [];
177
+
178
+ if (preset.provider && preset.model) {
179
+ parts.push(`${preset.provider}/${preset.model}`);
180
+ }
181
+ if (preset.thinkingLevel) {
182
+ parts.push(`thinking:${preset.thinkingLevel}`);
183
+ }
184
+ if (preset.tools) {
185
+ parts.push(`tools:${preset.tools.join(",")}`);
186
+ }
187
+ if (preset.instructions) {
188
+ const truncated =
189
+ preset.instructions.length > 30 ? `${preset.instructions.slice(0, 27)}...` : preset.instructions;
190
+ parts.push(`"${truncated}"`);
191
+ }
192
+
193
+ return parts.join(" | ");
194
+ }
195
+
196
+ /**
197
+ * Show preset selector UI using custom SelectList component.
198
+ */
199
+ async function showPresetSelector(ctx: ExtensionContext): Promise<void> {
200
+ const presetNames = Object.keys(presets);
201
+
202
+ if (presetNames.length === 0) {
203
+ ctx.ui.notify(
204
+ `No presets defined. Add presets to ${join(getAgentDir(), "presets.json")} or ${join(ctx.cwd, CONFIG_DIR_NAME, "presets.json")}`,
205
+ "warning",
206
+ );
207
+ return;
208
+ }
209
+
210
+ // Build select items with descriptions
211
+ const items: SelectItem[] = presetNames.map((name) => {
212
+ const preset = presets[name];
213
+ const isActive = name === activePresetName;
214
+ return {
215
+ value: name,
216
+ label: isActive ? `${name} (active)` : name,
217
+ description: buildPresetDescription(preset),
218
+ };
219
+ });
220
+
221
+ // Add "None" option to clear preset
222
+ items.push({
223
+ value: "(none)",
224
+ label: "(none)",
225
+ description: "Clear active preset, restore defaults",
226
+ });
227
+
228
+ const result = await ctx.ui.custom<string | null>((tui, theme, _kb, done) => {
229
+ const container = new Container();
230
+ container.addChild(new DynamicBorder((str) => theme.fg("accent", str)));
231
+
232
+ // Header
233
+ container.addChild(new Text(theme.fg("accent", theme.bold("Select Preset"))));
234
+
235
+ // SelectList with themed styling
236
+ const selectList = new SelectList(items, Math.min(items.length, 10), {
237
+ selectedPrefix: (text) => theme.fg("accent", text),
238
+ selectedText: (text) => theme.fg("accent", text),
239
+ description: (text) => theme.fg("muted", text),
240
+ scrollInfo: (text) => theme.fg("dim", text),
241
+ noMatch: (text) => theme.fg("warning", text),
242
+ });
243
+
244
+ selectList.onSelect = (item) => done(item.value);
245
+ selectList.onCancel = () => done(null);
246
+
247
+ container.addChild(selectList);
248
+
249
+ // Footer hint
250
+ container.addChild(new Text(theme.fg("dim", "↑↓ navigate • enter select • esc cancel")));
251
+
252
+ container.addChild(new DynamicBorder((str) => theme.fg("accent", str)));
253
+
254
+ return {
255
+ render(width: number) {
256
+ return container.render(width);
257
+ },
258
+ invalidate() {
259
+ container.invalidate();
260
+ },
261
+ handleInput(data: string) {
262
+ selectList.handleInput(data);
263
+ tui.requestRender();
264
+ },
265
+ };
266
+ });
267
+
268
+ if (!result) return;
269
+
270
+ if (result === "(none)") {
271
+ // Clear preset and restore original state
272
+ activePresetName = undefined;
273
+ activePreset = undefined;
274
+ if (originalState) {
275
+ if (originalState.model) {
276
+ await pi.setModel(originalState.model);
277
+ }
278
+ pi.setThinkingLevel(originalState.thinkingLevel);
279
+ pi.setActiveTools(originalState.tools);
280
+ } else {
281
+ pi.setActiveTools(["read", "bash", "edit", "write"]);
282
+ }
283
+ ctx.ui.notify("Preset cleared, defaults restored", "info");
284
+ updateStatus(ctx);
285
+ return;
286
+ }
287
+
288
+ const preset = presets[result];
289
+ if (preset) {
290
+ await applyPreset(result, preset, ctx);
291
+ ctx.ui.notify(`Preset "${result}" activated`, "info");
292
+ updateStatus(ctx);
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Update status indicator.
298
+ */
299
+ function updateStatus(ctx: ExtensionContext) {
300
+ if (activePresetName) {
301
+ ctx.ui.setStatus("preset", ctx.ui.theme.fg("accent", `preset:${activePresetName}`));
302
+ } else {
303
+ ctx.ui.setStatus("preset", undefined);
304
+ }
305
+ }
306
+
307
+ function getPresetOrder(): string[] {
308
+ return Object.keys(presets).sort();
309
+ }
310
+
311
+ async function cyclePreset(ctx: ExtensionContext): Promise<void> {
312
+ const presetNames = getPresetOrder();
313
+ if (presetNames.length === 0) {
314
+ ctx.ui.notify(
315
+ `No presets defined. Add presets to ${join(getAgentDir(), "presets.json")} or ${join(ctx.cwd, CONFIG_DIR_NAME, "presets.json")}`,
316
+ "warning",
317
+ );
318
+ return;
319
+ }
320
+
321
+ const cycleList = ["(none)", ...presetNames];
322
+ const currentName = activePresetName ?? "(none)";
323
+ const currentIndex = cycleList.indexOf(currentName);
324
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % cycleList.length;
325
+ const nextName = cycleList[nextIndex];
326
+
327
+ if (nextName === "(none)") {
328
+ activePresetName = undefined;
329
+ activePreset = undefined;
330
+ if (originalState) {
331
+ if (originalState.model) {
332
+ await pi.setModel(originalState.model);
333
+ }
334
+ pi.setThinkingLevel(originalState.thinkingLevel);
335
+ pi.setActiveTools(originalState.tools);
336
+ } else {
337
+ pi.setActiveTools(["read", "bash", "edit", "write"]);
338
+ }
339
+ ctx.ui.notify("Preset cleared, defaults restored", "info");
340
+ updateStatus(ctx);
341
+ return;
342
+ }
343
+
344
+ const preset = presets[nextName];
345
+ if (!preset) return;
346
+
347
+ await applyPreset(nextName, preset, ctx);
348
+ ctx.ui.notify(`Preset "${nextName}" activated`, "info");
349
+ updateStatus(ctx);
350
+ }
351
+
352
+ pi.registerShortcut(Key.ctrlShift("u"), {
353
+ description: "Cycle presets",
354
+ handler: async (ctx) => {
355
+ await cyclePreset(ctx);
356
+ },
357
+ });
358
+
359
+ // Register /preset command
360
+ pi.registerCommand("preset", {
361
+ description: "Switch preset configuration",
362
+ handler: async (args, ctx) => {
363
+ // If preset name provided, apply directly
364
+ if (args?.trim()) {
365
+ const name = args.trim();
366
+ const preset = presets[name];
367
+
368
+ if (!preset) {
369
+ const available = Object.keys(presets).join(", ") || "(none defined)";
370
+ ctx.ui.notify(`Unknown preset "${name}". Available: ${available}`, "error");
371
+ return;
372
+ }
373
+
374
+ await applyPreset(name, preset, ctx);
375
+ ctx.ui.notify(`Preset "${name}" activated`, "info");
376
+ updateStatus(ctx);
377
+ return;
378
+ }
379
+
380
+ // Otherwise show selector
381
+ await showPresetSelector(ctx);
382
+ },
383
+ });
384
+
385
+ // Inject preset instructions into system prompt
386
+ pi.on("before_agent_start", async (event) => {
387
+ if (activePreset?.instructions) {
388
+ return {
389
+ systemPrompt: `${event.systemPrompt}\n\n${activePreset.instructions}`,
390
+ };
391
+ }
392
+ });
393
+
394
+ // Initialize on session start
395
+ pi.on("session_start", async (_event, ctx) => {
396
+ // Load presets from config files
397
+ presets = loadPresets(ctx.cwd);
398
+
399
+ // Check for --preset flag
400
+ const presetFlag = pi.getFlag("preset");
401
+ if (typeof presetFlag === "string" && presetFlag) {
402
+ const preset = presets[presetFlag];
403
+ if (preset) {
404
+ await applyPreset(presetFlag, preset, ctx);
405
+ ctx.ui.notify(`Preset "${presetFlag}" activated`, "info");
406
+ } else {
407
+ const available = Object.keys(presets).join(", ") || "(none defined)";
408
+ ctx.ui.notify(`Unknown preset "${presetFlag}". Available: ${available}`, "warning");
409
+ }
410
+ }
411
+
412
+ // Restore preset from session state
413
+ const entries = ctx.sessionManager.getEntries();
414
+ const presetEntry = entries
415
+ .filter((e: { type: string; customType?: string }) => e.type === "custom" && e.customType === "preset-state")
416
+ .pop() as { data?: { name: string } } | undefined;
417
+
418
+ if (presetEntry?.data?.name && !presetFlag) {
419
+ const preset = presets[presetEntry.data.name];
420
+ if (preset) {
421
+ activePresetName = presetEntry.data.name;
422
+ activePreset = preset;
423
+ // Don't re-apply model/tools on restore, just keep the name for instructions
424
+ }
425
+ }
426
+
427
+ updateStatus(ctx);
428
+ });
429
+
430
+ // Persist preset state
431
+ pi.on("turn_start", async () => {
432
+ if (activePresetName) {
433
+ pi.appendEntry("preset-state", { name: activePresetName });
434
+ }
435
+ });
436
+ }