@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,904 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { registerThinkingLabeling } from "../src/thinking-label.ts";
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+
9
+ type CapturedHandler = (
10
+ event: unknown,
11
+ ctx?: unknown,
12
+ ) => Promise<void> | void;
13
+
14
+ function captureThinkingHandlers(): Map<string, CapturedHandler> {
15
+ const handlers = new Map<string, CapturedHandler>();
16
+ registerThinkingLabeling({
17
+ on(eventName: string, handler: CapturedHandler): void {
18
+ handlers.set(eventName, handler);
19
+ },
20
+ } as never);
21
+ return handlers;
22
+ }
23
+
24
+ const PASSTHROUGH_THEME = {
25
+ fg: (_color: string, text: string) => text,
26
+ };
27
+
28
+ const ANSI_THEME = {
29
+ fg: (color: string, text: string) => `\x1b[38;2;100;200;255m[${color}]${text}\x1b[0m`,
30
+ };
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // message_update / message_end thinking-label formatting edge cases
34
+ // ---------------------------------------------------------------------------
35
+
36
+ test("message_update duplicates: single 'Thinking:' prefix is normalized away", async () => {
37
+ const handlers = captureThinkingHandlers();
38
+ const event = {
39
+ message: {
40
+ role: "assistant",
41
+ api: "anthropic-messages",
42
+ content: [{ type: "thinking", thinking: "Thinking: reasoning about X" }],
43
+ },
44
+ };
45
+
46
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
47
+
48
+ assert.equal(event.message.content[0].thinking, "Thinking: reasoning about X");
49
+ });
50
+
51
+ test("message_update duplicates: lowercase 'thinking:' prefix is normalized away", async () => {
52
+ const handlers = captureThinkingHandlers();
53
+ const event = {
54
+ message: {
55
+ role: "assistant",
56
+ api: "anthropic-messages",
57
+ content: [{ type: "thinking", thinking: "thinking: checking paths" }],
58
+ },
59
+ };
60
+
61
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
62
+
63
+ assert.equal(event.message.content[0].thinking, "Thinking: checking paths");
64
+ });
65
+
66
+ test("message_update duplicates: uppercase 'THINKING:' prefix is normalized away", async () => {
67
+ const handlers = captureThinkingHandlers();
68
+ const event = {
69
+ message: {
70
+ role: "assistant",
71
+ api: "anthropic-messages",
72
+ content: [{ type: "thinking", thinking: "THINKING: uppercased reasoning" }],
73
+ },
74
+ };
75
+
76
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
77
+
78
+ assert.equal(event.message.content[0].thinking, "Thinking: uppercased reasoning");
79
+ });
80
+
81
+ test("message_update duplicates: repeated 'Thinking: Thinking:' prefix is fully stripped", async () => {
82
+ const handlers = captureThinkingHandlers();
83
+ const event = {
84
+ message: {
85
+ role: "assistant",
86
+ api: "anthropic-messages",
87
+ content: [{ type: "thinking", thinking: "Thinking: Thinking: double label content" }],
88
+ },
89
+ };
90
+
91
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
92
+
93
+ assert.equal(event.message.content[0].thinking, "Thinking: double label content");
94
+ });
95
+
96
+ test("message_update duplicates: interleaved case 'thinking: Thinking:' is fully stripped", async () => {
97
+ const handlers = captureThinkingHandlers();
98
+ const event = {
99
+ message: {
100
+ role: "assistant",
101
+ api: "anthropic-messages",
102
+ content: [{ type: "thinking", thinking: "thinking: Thinking: mixed case double" }],
103
+ },
104
+ };
105
+
106
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
107
+
108
+ assert.equal(event.message.content[0].thinking, "Thinking: mixed case double");
109
+ });
110
+
111
+ test("message_update duplicates: triple label 'thinking: thinking: Thinking:' is fully stripped", async () => {
112
+ const handlers = captureThinkingHandlers();
113
+ const event = {
114
+ message: {
115
+ role: "assistant",
116
+ api: "anthropic-messages",
117
+ content: [{ type: "thinking", thinking: "thinking: thinking: Thinking: triple" }],
118
+ },
119
+ };
120
+
121
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
122
+
123
+ assert.equal(event.message.content[0].thinking, "Thinking: triple");
124
+ });
125
+
126
+ test("message_update duplicates: indented label ' Thinking: content' is handled", async () => {
127
+ const handlers = captureThinkingHandlers();
128
+ const event = {
129
+ message: {
130
+ role: "assistant",
131
+ api: "anthropic-messages",
132
+ content: [{ type: "thinking", thinking: " Thinking: indented content" }],
133
+ },
134
+ };
135
+
136
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
137
+
138
+ assert.equal(event.message.content[0].thinking, "Thinking: indented content");
139
+ });
140
+
141
+ // ---------------------------------------------------------------------------
142
+ // ANSI fragments interleaved with labels
143
+ // ---------------------------------------------------------------------------
144
+
145
+ test("message_update ANSI: SGR code before thinking label is stripped", async () => {
146
+ const handlers = captureThinkingHandlers();
147
+ const event = {
148
+ message: {
149
+ role: "assistant",
150
+ api: "anthropic-messages",
151
+ content: [{ type: "thinking", thinking: "\x1b[31mThinking: red-tinted reasoning" }],
152
+ },
153
+ };
154
+
155
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
156
+
157
+ assert.equal(event.message.content[0].thinking, "Thinking: red-tinted reasoning");
158
+ });
159
+
160
+ test("message_update ANSI: multiple SGR codes before label are all stripped", async () => {
161
+ const handlers = captureThinkingHandlers();
162
+ const event = {
163
+ message: {
164
+ role: "assistant",
165
+ api: "anthropic-messages",
166
+ content: [{ type: "thinking", thinking: "\x1b[1m\x1b[32mThinking: bold green label\x1b[0m" }],
167
+ },
168
+ };
169
+
170
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
171
+
172
+ // stripAnsi inside stripThinkingPresentationArtifacts removes ALL ANSI codes
173
+ assert.equal(event.message.content[0].thinking, "Thinking: bold green label");
174
+ });
175
+
176
+ test("message_update ANSI: fragment starting with semicolon is stripped as leading artifact", async () => {
177
+ const handlers = captureThinkingHandlers();
178
+ const event = {
179
+ message: {
180
+ role: "assistant",
181
+ api: "anthropic-messages",
182
+ content: [{ type: "thinking", thinking: ";1;31mThinking: fragment artifact content" }],
183
+ },
184
+ };
185
+
186
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
187
+
188
+ assert.equal(event.message.content[0].thinking, "Thinking: fragment artifact content");
189
+ });
190
+
191
+ test("message_update ANSI: striped background code before label is removed", async () => {
192
+ const handlers = captureThinkingHandlers();
193
+ const event = {
194
+ message: {
195
+ role: "assistant",
196
+ api: "anthropic-messages",
197
+ content: [{ type: "thinking", thinking: "\x1b[48;5;24mThinking: bg colored reasoning" }],
198
+ },
199
+ };
200
+
201
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
202
+
203
+ assert.equal(event.message.content[0].thinking, "Thinking: bg colored reasoning");
204
+ });
205
+
206
+ test("message_update ANSI: exposed fragment after removing first label reveals second label", async () => {
207
+ const handlers = captureThinkingHandlers();
208
+ const event = {
209
+ message: {
210
+ role: "assistant",
211
+ api: "anthropic-messages",
212
+ content: [{ type: "thinking", thinking: "\x1b[31mThinking: \x1b[0mThinking: double with ANSI between" }],
213
+ },
214
+ };
215
+
216
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
217
+
218
+ // After stripping ANSI: "Thinking: Thinking: double with ANSI between"
219
+ // After stripping first label: "Thinking: double with ANSI between"
220
+ // After stripping second label: "double with ANSI between"
221
+ // So result should have single "Thinking: " prefix
222
+ assert.equal(event.message.content[0].thinking, "Thinking: double with ANSI between");
223
+ });
224
+
225
+ // ---------------------------------------------------------------------------
226
+ // Provider API name handling
227
+ // ---------------------------------------------------------------------------
228
+
229
+ test("message_update API: anthropic-messages gets thinking prefix", async () => {
230
+ const handlers = captureThinkingHandlers();
231
+ const event = {
232
+ message: {
233
+ role: "assistant",
234
+ api: "anthropic-messages",
235
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
236
+ },
237
+ };
238
+
239
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
240
+
241
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
242
+ });
243
+
244
+ test("message_update API: openai-completions gets thinking prefix", async () => {
245
+ const handlers = captureThinkingHandlers();
246
+ const event = {
247
+ message: {
248
+ role: "assistant",
249
+ api: "openai-completions",
250
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
251
+ },
252
+ };
253
+
254
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
255
+
256
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
257
+ });
258
+
259
+ test("message_update API: openai-responses gets thinking prefix", async () => {
260
+ const handlers = captureThinkingHandlers();
261
+ const event = {
262
+ message: {
263
+ role: "assistant",
264
+ api: "openai-responses",
265
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
266
+ },
267
+ };
268
+
269
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
270
+
271
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
272
+ });
273
+
274
+ test("message_update API: openai-codex-responses gets thinking prefix", async () => {
275
+ const handlers = captureThinkingHandlers();
276
+ const event = {
277
+ message: {
278
+ role: "assistant",
279
+ api: "openai-codex-responses",
280
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
281
+ },
282
+ };
283
+
284
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
285
+
286
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
287
+ });
288
+
289
+ test("message_update API: openai-chat does NOT get thinking prefix", async () => {
290
+ const handlers = captureThinkingHandlers();
291
+ const event = {
292
+ message: {
293
+ role: "assistant",
294
+ api: "openai-chat",
295
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
296
+ },
297
+ };
298
+
299
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
300
+
301
+ assert.strictEqual(event.message.content[0].thinking, "raw reasoning");
302
+ });
303
+
304
+ test("message_update API: openai-unknown-future does NOT get thinking prefix", async () => {
305
+ const handlers = captureThinkingHandlers();
306
+ const event = {
307
+ message: {
308
+ role: "assistant",
309
+ api: "openai-unknown-future",
310
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
311
+ },
312
+ };
313
+
314
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
315
+
316
+ assert.strictEqual(event.message.content[0].thinking, "raw reasoning");
317
+ });
318
+
319
+ test("message_update API: undefined API gets thinking prefix (default)", async () => {
320
+ const handlers = captureThinkingHandlers();
321
+ const event = {
322
+ message: {
323
+ role: "assistant",
324
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
325
+ },
326
+ };
327
+
328
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
329
+
330
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
331
+ });
332
+
333
+ test("message_update API: empty string API gets thinking prefix (default)", async () => {
334
+ const handlers = captureThinkingHandlers();
335
+ const event = {
336
+ message: {
337
+ role: "assistant",
338
+ api: "",
339
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
340
+ },
341
+ };
342
+
343
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
344
+
345
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
346
+ });
347
+
348
+ test("message_update API: random non-OpenAI provider gets thinking prefix", async () => {
349
+ const handlers = captureThinkingHandlers();
350
+ const event = {
351
+ message: {
352
+ role: "assistant",
353
+ api: "custom-provider-v1",
354
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
355
+ },
356
+ };
357
+
358
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
359
+
360
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
361
+ });
362
+
363
+ test("message_update API: anthropic-responses gets thinking prefix", async () => {
364
+ const handlers = captureThinkingHandlers();
365
+ const event = {
366
+ message: {
367
+ role: "assistant",
368
+ api: "anthropic-responses",
369
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
370
+ },
371
+ };
372
+
373
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
374
+
375
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
376
+ });
377
+
378
+ test("message_update API: anthropic-completions gets thinking prefix", async () => {
379
+ const handlers = captureThinkingHandlers();
380
+ const event = {
381
+ message: {
382
+ role: "assistant",
383
+ api: "anthropic-completions",
384
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
385
+ },
386
+ };
387
+
388
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
389
+
390
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
391
+ });
392
+
393
+ test("message_update API: unknown anthropic- prefix gets thinking prefix", async () => {
394
+ const handlers = captureThinkingHandlers();
395
+ const event = {
396
+ message: {
397
+ role: "assistant",
398
+ api: "anthropic-experimental-v3",
399
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
400
+ },
401
+ };
402
+
403
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
404
+
405
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
406
+ });
407
+
408
+ test("message_update API: case-insensitive normalization of openai-completions", async () => {
409
+ const handlers = captureThinkingHandlers();
410
+ const event = {
411
+ message: {
412
+ role: "assistant",
413
+ api: "OpenAI-Completions",
414
+ content: [{ type: "thinking", thinking: "raw reasoning" }],
415
+ },
416
+ };
417
+
418
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
419
+
420
+ assert.equal(event.message.content[0].thinking, "Thinking: raw reasoning");
421
+ });
422
+
423
+ // ---------------------------------------------------------------------------
424
+ // message_end event behavior (same logic, persists labels)
425
+ // ---------------------------------------------------------------------------
426
+
427
+ test("message_end: attaches thinking label on final message", async () => {
428
+ const handlers = captureThinkingHandlers();
429
+ const event = {
430
+ message: {
431
+ role: "assistant",
432
+ api: "anthropic-messages",
433
+ content: [{ type: "thinking", thinking: "final reasoning" }],
434
+ },
435
+ };
436
+
437
+ await handlers.get("message_end")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
438
+
439
+ assert.equal(event.message.content[0].thinking, "Thinking: final reasoning");
440
+ });
441
+
442
+ test("message_end: respects openai-* exclusion", async () => {
443
+ const handlers = captureThinkingHandlers();
444
+ const event = {
445
+ message: {
446
+ role: "assistant",
447
+ api: "openai-chat",
448
+ content: [{ type: "thinking", thinking: "final reasoning" }],
449
+ },
450
+ };
451
+
452
+ await handlers.get("message_end")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
453
+
454
+ assert.strictEqual(event.message.content[0].thinking, "final reasoning");
455
+ });
456
+
457
+ test("message_end: applies theme to label", async () => {
458
+ const handlers = captureThinkingHandlers();
459
+ const event = {
460
+ message: {
461
+ role: "assistant",
462
+ api: "anthropic-messages",
463
+ content: [{ type: "thinking", thinking: "themed reasoning" }],
464
+ },
465
+ };
466
+
467
+ await handlers.get("message_end")?.(event, { ui: { theme: ANSI_THEME } });
468
+
469
+ assert.match(event.message.content[0].thinking, /^\x1b\[38;2;100;200;255m\[accent\]Thinking:/);
470
+ });
471
+
472
+ // ---------------------------------------------------------------------------
473
+ // context event behavior (sanitization strips labels for LLM context)
474
+ // ---------------------------------------------------------------------------
475
+
476
+ test("context: strips thinking labels from assistant messages", async () => {
477
+ const handlers = captureThinkingHandlers();
478
+ const event = {
479
+ messages: [
480
+ {
481
+ role: "assistant",
482
+ content: [
483
+ { type: "thinking", thinking: "Thinking: labeled reasoning for model" },
484
+ ],
485
+ },
486
+ ],
487
+ };
488
+
489
+ await handlers.get("context")?.(event, {});
490
+
491
+ assert.equal(event.messages[0].content[0].thinking, "labeled reasoning for model");
492
+ });
493
+
494
+ test("context: strips thinking labels even with ANSI wrapping", async () => {
495
+ const handlers = captureThinkingHandlers();
496
+ const event = {
497
+ messages: [
498
+ {
499
+ role: "assistant",
500
+ content: [
501
+ { type: "thinking", thinking: "\x1b[31mThinking: \x1b[0mansi reasoning" },
502
+ ],
503
+ },
504
+ ],
505
+ };
506
+
507
+ await handlers.get("context")?.(event, {});
508
+
509
+ assert.equal(event.messages[0].content[0].thinking, "ansi reasoning");
510
+ });
511
+
512
+ test("context: preserves non-thinking blocks unchanged", async () => {
513
+ const handlers = captureThinkingHandlers();
514
+ const textBlock = { type: "text", text: "hello" };
515
+ const thinkingBlock = { type: "thinking", thinking: "Thinking: labeled" };
516
+ const event = {
517
+ messages: [
518
+ {
519
+ role: "assistant",
520
+ content: [textBlock, thinkingBlock],
521
+ },
522
+ ],
523
+ };
524
+
525
+ await handlers.get("context")?.(event, {});
526
+
527
+ assert.strictEqual(event.messages[0].content[0], textBlock);
528
+ assert.equal((event.messages[0].content[1] as { thinking: string }).thinking, "labeled");
529
+ });
530
+
531
+ test("context: does not modify non-assistant messages", async () => {
532
+ const handlers = captureThinkingHandlers();
533
+ const userMessage = { role: "user", content: "hello" };
534
+ const event = {
535
+ messages: [userMessage],
536
+ };
537
+
538
+ await handlers.get("context")?.(event, {});
539
+
540
+ assert.strictEqual(event.messages[0], userMessage);
541
+ });
542
+
543
+ test("context: handles events with non-array messages gracefully", async () => {
544
+ const handlers = captureThinkingHandlers();
545
+
546
+ // Should not throw for non-array messages
547
+ await handlers.get("context")?.({ messages: "not an array" }, {});
548
+ await handlers.get("context")?.({ messages: null }, {});
549
+ await handlers.get("context")?.({ messages: undefined }, {});
550
+ await handlers.get("context")?.({}, {});
551
+
552
+ assert.ok(true, "context handler did not throw");
553
+ });
554
+
555
+ test("context: handles events with missing messages property", async () => {
556
+ const handlers = captureThinkingHandlers();
557
+
558
+ await handlers.get("context")?.({ unrelated: true }, {});
559
+
560
+ assert.ok(true, "context handler did not throw on missing messages");
561
+ });
562
+
563
+ test("context: strips duplicate labels in context", async () => {
564
+ const handlers = captureThinkingHandlers();
565
+ const event = {
566
+ messages: [
567
+ {
568
+ role: "assistant",
569
+ content: [
570
+ { type: "thinking", thinking: "Thinking: Thinking: double label" },
571
+ ],
572
+ },
573
+ ],
574
+ };
575
+
576
+ await handlers.get("context")?.(event, {});
577
+
578
+ assert.equal(event.messages[0].content[0].thinking, "double label");
579
+ });
580
+
581
+ test("context: strips lowercase thinking: label", async () => {
582
+ const handlers = captureThinkingHandlers();
583
+ const event = {
584
+ messages: [
585
+ {
586
+ role: "assistant",
587
+ content: [
588
+ { type: "thinking", thinking: "thinking: lowercase prefix" },
589
+ ],
590
+ },
591
+ ],
592
+ };
593
+
594
+ await handlers.get("context")?.(event, {});
595
+
596
+ assert.equal(event.messages[0].content[0].thinking, "lowercase prefix");
597
+ });
598
+
599
+ // ---------------------------------------------------------------------------
600
+ // Malformed content arrays – handlers must be resilient
601
+ // ---------------------------------------------------------------------------
602
+
603
+ test("message_update malformed: null content array item passes through", async () => {
604
+ const handlers = captureThinkingHandlers();
605
+ const event = {
606
+ message: {
607
+ role: "assistant",
608
+ api: "anthropic-messages",
609
+ content: [null, { type: "thinking", thinking: "reasoning" }],
610
+ },
611
+ };
612
+
613
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
614
+
615
+ assert.strictEqual(event.message.content[0], null);
616
+ assert.equal(event.message.content[1].thinking, "Thinking: reasoning");
617
+ });
618
+
619
+ test("message_update malformed: undefined content array item passes through", async () => {
620
+ const handlers = captureThinkingHandlers();
621
+ const event = {
622
+ message: {
623
+ role: "assistant",
624
+ api: "anthropic-messages",
625
+ content: [undefined, { type: "thinking", thinking: "reasoning" }],
626
+ },
627
+ };
628
+
629
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
630
+
631
+ assert.strictEqual(event.message.content[0], undefined);
632
+ assert.equal(event.message.content[1].thinking, "Thinking: reasoning");
633
+ });
634
+
635
+ test("message_update malformed: non-array content passes through unchanged", async () => {
636
+ const handlers = captureThinkingHandlers();
637
+ const content = { type: "thinking", thinking: "not in array" };
638
+ const event = {
639
+ message: {
640
+ role: "assistant",
641
+ api: "anthropic-messages",
642
+ content,
643
+ },
644
+ };
645
+
646
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
647
+
648
+ assert.strictEqual(event.message.content, content);
649
+ });
650
+
651
+ test("message_update malformed: nested array content passes through unchanged", async () => {
652
+ const handlers = captureThinkingHandlers();
653
+ // Content IS an array with a thinking block — it will be processed.
654
+ const nested = [{ type: "thinking", thinking: "nested reasoning" }];
655
+ const event = {
656
+ message: {
657
+ role: "assistant",
658
+ api: "anthropic-messages",
659
+ content: nested,
660
+ },
661
+ };
662
+
663
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
664
+
665
+ // Since content is an array containing a valid thinking block, the label IS added.
666
+ assert.equal(event.message.content[0].thinking, "Thinking: nested reasoning");
667
+ });
668
+
669
+ test("message_update malformed: empty content array is a no-op", async () => {
670
+ const handlers = captureThinkingHandlers();
671
+ const event = {
672
+ message: {
673
+ role: "assistant",
674
+ api: "anthropic-messages",
675
+ content: [],
676
+ },
677
+ };
678
+
679
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
680
+
681
+ assert.deepEqual(event.message.content, []);
682
+ });
683
+
684
+ test("message_update malformed: non-string thinking field is left untouched", async () => {
685
+ const handlers = captureThinkingHandlers();
686
+ const block = { type: "thinking", thinking: 42 as unknown as string };
687
+ const event = {
688
+ message: {
689
+ role: "assistant",
690
+ api: "anthropic-messages",
691
+ content: [block],
692
+ },
693
+ };
694
+
695
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
696
+
697
+ assert.strictEqual(event.message.content[0].thinking, 42);
698
+ });
699
+
700
+ test("message_update malformed: block with null thinking field is left untouched", async () => {
701
+ const handlers = captureThinkingHandlers();
702
+ const block = { type: "thinking", thinking: null as unknown as string };
703
+ const event = {
704
+ message: {
705
+ role: "assistant",
706
+ api: "anthropic-messages",
707
+ content: [block],
708
+ },
709
+ };
710
+
711
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
712
+
713
+ assert.strictEqual(event.message.content[0].thinking, null);
714
+ });
715
+
716
+ test("message_update malformed: mixed valid and invalid blocks only processes valid ones", async () => {
717
+ const handlers = captureThinkingHandlers();
718
+ const invalid = { type: "other", data: "skip" };
719
+ const valid = { type: "thinking", thinking: "valid reasoning" };
720
+ const event = {
721
+ message: {
722
+ role: "assistant",
723
+ api: "anthropic-messages",
724
+ content: [invalid, valid, null],
725
+ },
726
+ };
727
+
728
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
729
+
730
+ assert.strictEqual(event.message.content[0], invalid);
731
+ assert.equal((event.message.content[1] as { thinking: string }).thinking, "Thinking: valid reasoning");
732
+ assert.strictEqual(event.message.content[2], null);
733
+ });
734
+
735
+ test("message_update malformed: content is a plain string, not array, passes through", async () => {
736
+ const handlers = captureThinkingHandlers();
737
+ const event = {
738
+ message: {
739
+ role: "assistant",
740
+ api: "anthropic-messages",
741
+ content: "just a string, not an array of blocks",
742
+ },
743
+ };
744
+
745
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
746
+
747
+ assert.equal(event.message.content, "just a string, not an array of blocks");
748
+ });
749
+
750
+ // ---------------------------------------------------------------------------
751
+ // Non-English / custom thinking label patterns (should pass through)
752
+ // ---------------------------------------------------------------------------
753
+
754
+ test("message_update non-English: Japanese thinking label gets Thinking: prefix since pattern not matched", async () => {
755
+ const handlers = captureThinkingHandlers();
756
+ const event = {
757
+ message: {
758
+ role: "assistant",
759
+ api: "anthropic-messages",
760
+ content: [{ type: "thinking", thinking: "思考: 日本語の推論" }],
761
+ },
762
+ };
763
+
764
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
765
+
766
+ // The non-English prefix does not match /^thinking:/i so the original text
767
+ // is NOT deduplicated, but the standard "Thinking: " prefix IS prepended.
768
+ assert.equal(event.message.content[0].thinking, "Thinking: 思考: 日本語の推論");
769
+ });
770
+
771
+ test("message_update non-English: French thinking label gets Thinking: prefix", async () => {
772
+ const handlers = captureThinkingHandlers();
773
+ const event = {
774
+ message: {
775
+ role: "assistant",
776
+ api: "anthropic-messages",
777
+ content: [{ type: "thinking", thinking: "Réflexion: raisonnement en français" }],
778
+ },
779
+ };
780
+
781
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
782
+
783
+ assert.equal(event.message.content[0].thinking, "Thinking: Réflexion: raisonnement en français");
784
+ });
785
+
786
+ test("message_update custom: 'Analyzing:' prefix gets Thinking: prefix (not matched by pattern)", async () => {
787
+ const handlers = captureThinkingHandlers();
788
+ const event = {
789
+ message: {
790
+ role: "assistant",
791
+ api: "anthropic-messages",
792
+ content: [{ type: "thinking", thinking: "Analyzing: code structure" }],
793
+ },
794
+ };
795
+
796
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
797
+
798
+ assert.equal(event.message.content[0].thinking, "Thinking: Analyzing: code structure");
799
+ });
800
+
801
+ test("message_update custom: 'Note:' prefix gets Thinking: prefix", async () => {
802
+ const handlers = captureThinkingHandlers();
803
+ const event = {
804
+ message: {
805
+ role: "assistant",
806
+ api: "anthropic-messages",
807
+ content: [{ type: "thinking", thinking: "Note: additional context" }],
808
+ },
809
+ };
810
+
811
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
812
+
813
+ assert.equal(event.message.content[0].thinking, "Thinking: Note: additional context");
814
+ });
815
+
816
+ // ---------------------------------------------------------------------------
817
+ // Non-assistant role in event – should be skipped
818
+ // ---------------------------------------------------------------------------
819
+
820
+ test("message_update: non-assistant role messages are skipped", async () => {
821
+ const handlers = captureThinkingHandlers();
822
+ const event = {
823
+ message: {
824
+ role: "user",
825
+ api: "anthropic-messages",
826
+ content: [{ type: "thinking", thinking: "user thinking" }],
827
+ },
828
+ };
829
+
830
+ // Should not throw and should not modify content
831
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
832
+
833
+ assert.ok(true, "non-assistant message update did not throw");
834
+ });
835
+
836
+ test("message_end: non-assistant role messages are skipped", async () => {
837
+ const handlers = captureThinkingHandlers();
838
+ const event = {
839
+ message: {
840
+ role: "user",
841
+ api: "anthropic-messages",
842
+ content: [{ type: "thinking", thinking: "user thinking end" }],
843
+ },
844
+ };
845
+
846
+ await handlers.get("message_end")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
847
+
848
+ assert.ok(true, "non-assistant message end did not throw");
849
+ });
850
+
851
+ // ---------------------------------------------------------------------------
852
+ // No-theme fallback (plain "Thinking: " prefix)
853
+ // ---------------------------------------------------------------------------
854
+
855
+ test("message_update: no theme falls back to plain 'Thinking: ' prefix", async () => {
856
+ const handlers = captureThinkingHandlers();
857
+ const event = {
858
+ message: {
859
+ role: "assistant",
860
+ api: "anthropic-messages",
861
+ content: [{ type: "thinking", thinking: "no theme reasoning" }],
862
+ },
863
+ };
864
+
865
+ await handlers.get("message_update")?.(event, { ui: {} });
866
+
867
+ assert.equal(event.message.content[0].thinking, "Thinking: no theme reasoning");
868
+ });
869
+
870
+ test("message_update: no theme and undefined ctx.ui is handled gracefully", async () => {
871
+ const handlers = captureThinkingHandlers();
872
+ const event = {
873
+ message: {
874
+ role: "assistant",
875
+ api: "anthropic-messages",
876
+ content: [{ type: "thinking", thinking: "no ctx at all" }],
877
+ },
878
+ };
879
+
880
+ // ctx is undefined entirely
881
+ await handlers.get("message_update")?.(event, undefined);
882
+
883
+ assert.ok(true, "handled undefined ctx without throwing");
884
+ });
885
+
886
+ // ---------------------------------------------------------------------------
887
+ // Edge: content with only whitespace after stripping
888
+ // ---------------------------------------------------------------------------
889
+
890
+ test("message_update: content that becomes empty after stripping keeps original text", async () => {
891
+ const handlers = captureThinkingHandlers();
892
+ const event = {
893
+ message: {
894
+ role: "assistant",
895
+ api: "anthropic-messages",
896
+ content: [{ type: "thinking", thinking: "Thinking: " }],
897
+ },
898
+ };
899
+
900
+ await handlers.get("message_update")?.(event, { ui: { theme: PASSTHROUGH_THEME } });
901
+
902
+ // After stripping "Thinking:" the remainder is whitespace → trimmed to empty → keep original
903
+ assert.equal(event.message.content[0].thinking, "Thinking: ");
904
+ });