@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,886 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { Box, visibleWidth, type Component } from "@earendil-works/pi-tui";
4
+ import {
5
+ normalizeDiffRenderWidth,
6
+ resolveDiffPresentationMode,
7
+ buildDiffSummaryText,
8
+ } from "../src/diff-presentation.ts";
9
+ import {
10
+ renderEditDiffResult,
11
+ renderWriteDiffResult,
12
+ } from "../src/diff-renderer.ts";
13
+ import type { ToolDisplayConfig } from "../src/types.ts";
14
+
15
+ // ─── Test helpers ──────────────────────────────────────────────────────────
16
+
17
+ const passThroughTheme = {
18
+ fg: (_color: string, text: string): string => text,
19
+ bold: (text: string): string => text,
20
+ };
21
+
22
+ const defaultConfig: Partial<ToolDisplayConfig> = {
23
+ diffViewMode: "auto",
24
+ diffSplitMinWidth: 80,
25
+ diffCollapsedLines: 24,
26
+ diffWordWrap: false,
27
+ diffIndicatorMode: "bars",
28
+ };
29
+
30
+ function renderInsideToolBox(component: Component, width: number): string[] {
31
+ const box = new Box(1, 1);
32
+ box.addChild(component);
33
+ return box.render(width);
34
+ }
35
+
36
+ // ─── normalizeDiffRenderWidth extreme values ───────────────────────────────
37
+
38
+ test("normalizeDiffRenderWidth returns 0 for negative values", () => {
39
+ assert.equal(normalizeDiffRenderWidth(-1), 0);
40
+ assert.equal(normalizeDiffRenderWidth(-100), 0);
41
+ });
42
+
43
+ test("normalizeDiffRenderWidth returns 0 for NaN", () => {
44
+ assert.equal(normalizeDiffRenderWidth(NaN), 0);
45
+ });
46
+
47
+ test("normalizeDiffRenderWidth returns 0 for Infinity", () => {
48
+ assert.equal(normalizeDiffRenderWidth(Infinity), 0);
49
+ assert.equal(normalizeDiffRenderWidth(-Infinity), 0);
50
+ });
51
+
52
+ test("normalizeDiffRenderWidth returns 0 for zero", () => {
53
+ assert.equal(normalizeDiffRenderWidth(0), 0);
54
+ });
55
+
56
+ test("normalizeDiffRenderWidth floors to integer", () => {
57
+ assert.equal(normalizeDiffRenderWidth(10.7), 10);
58
+ assert.equal(normalizeDiffRenderWidth(99.99), 99);
59
+ });
60
+
61
+ test("normalizeDiffRenderWidth clamps negative floor result to 0", () => {
62
+ // normalizeDiffRenderWidth(-0.5): Number.isFinite(-0.5) → true, Math.floor(-0.5) → -1, Math.max(0, -1) → 0
63
+ assert.equal(normalizeDiffRenderWidth(-0.5), 0);
64
+ });
65
+
66
+ test("normalizeDiffRenderWidth returns positive integers as-is", () => {
67
+ assert.equal(normalizeDiffRenderWidth(1), 1);
68
+ assert.equal(normalizeDiffRenderWidth(80), 80);
69
+ assert.equal(normalizeDiffRenderWidth(999), 999);
70
+ });
71
+
72
+ // ─── resolveDiffPresentationMode all branches ──────────────────────────────
73
+
74
+ test("resolveDiffPresentationMode returns summary when width < 8", () => {
75
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 80 };
76
+ assert.equal(resolveDiffPresentationMode(config, 0, true), "summary");
77
+ assert.equal(resolveDiffPresentationMode(config, 7, true), "summary");
78
+ assert.equal(resolveDiffPresentationMode(config, -1, true), "summary");
79
+ });
80
+
81
+ test("resolveDiffPresentationMode returns compact when 8 <= width < 18", () => {
82
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 80 };
83
+ assert.equal(resolveDiffPresentationMode(config, 8, true), "compact");
84
+ assert.equal(resolveDiffPresentationMode(config, 12, true), "compact");
85
+ assert.equal(resolveDiffPresentationMode(config, 17, true), "compact");
86
+ });
87
+
88
+ test("resolveDiffPresentationMode returns unified when mode is unified", () => {
89
+ const config = { diffViewMode: "unified" as const, diffSplitMinWidth: 80 };
90
+ assert.equal(resolveDiffPresentationMode(config, 80, true), "unified");
91
+ assert.equal(resolveDiffPresentationMode(config, 200, true), "unified");
92
+ });
93
+
94
+ test("resolveDiffPresentationMode split falls back to unified when canRenderSplitLayout is false", () => {
95
+ const config = { diffViewMode: "split" as const, diffSplitMinWidth: 80 };
96
+ assert.equal(resolveDiffPresentationMode(config, 80, false), "unified");
97
+ });
98
+
99
+ test("resolveDiffPresentationMode returns split when mode is split and canRenderSplitLayout", () => {
100
+ const config = { diffViewMode: "split" as const, diffSplitMinWidth: 80 };
101
+ assert.equal(resolveDiffPresentationMode(config, 80, true), "split");
102
+ });
103
+
104
+ test("resolveDiffPresentationMode auto mode returns split when width >= diffSplitMinWidth and canRenderSplitLayout", () => {
105
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 100 };
106
+ assert.equal(resolveDiffPresentationMode(config, 100, true), "split");
107
+ assert.equal(resolveDiffPresentationMode(config, 120, true), "split");
108
+ });
109
+
110
+ test("resolveDiffPresentationMode auto mode returns unified when width >= 18 but < diffSplitMinWidth", () => {
111
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 120 };
112
+ assert.equal(resolveDiffPresentationMode(config, 80, true), "unified");
113
+ });
114
+
115
+ test("resolveDiffPresentationMode auto mode returns unified when canRenderSplitLayout is false", () => {
116
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 80 };
117
+ assert.equal(resolveDiffPresentationMode(config, 80, false), "unified");
118
+ });
119
+
120
+ test("resolveDiffPresentationMode auto mode returns unified when width >= diffSplitMinWidth but canRenderSplitLayout is false", () => {
121
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 80 };
122
+ assert.equal(resolveDiffPresentationMode(config, 120, false), "unified");
123
+ });
124
+
125
+ test("resolveDiffPresentationMode handles NaN width safely", () => {
126
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 80 };
127
+ assert.equal(resolveDiffPresentationMode(config, NaN, true), "summary");
128
+ });
129
+
130
+ test("resolveDiffPresentationMode handles Infinity width safely", () => {
131
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 80 };
132
+ assert.equal(resolveDiffPresentationMode(config, Infinity, true), "summary");
133
+ });
134
+
135
+ // ─── Empty diff ────────────────────────────────────────────────────────────
136
+
137
+ test("renderEditDiffResult handles entirely empty diff string", () => {
138
+ const component = renderEditDiffResult(
139
+ { diff: "" },
140
+ { expanded: true },
141
+ { diffViewMode: "auto", diffSplitMinWidth: 80, diffCollapsedLines: 24, diffWordWrap: false } as any,
142
+ passThroughTheme,
143
+ "",
144
+ );
145
+ const lines = renderInsideToolBox(component, 80);
146
+ assert.ok(lines.length > 0);
147
+ assert.ok(lines.some((line) => line.includes("no diff payload")));
148
+ });
149
+
150
+ test("renderEditDiffResult handles diff with only whitespace", () => {
151
+ const component = renderEditDiffResult(
152
+ { diff: " \n \n" },
153
+ { expanded: true },
154
+ defaultConfig as any,
155
+ passThroughTheme,
156
+ "",
157
+ );
158
+ const lines = renderInsideToolBox(component, 80);
159
+ // Whitespace-only diff is treated as empty → shows no diff payload
160
+ assert.ok(lines.some((line) => line.includes("no diff")));
161
+ });
162
+
163
+ test("renderEditDiffResult handles diff with no actual changes (only file headers)", () => {
164
+ const component = renderEditDiffResult(
165
+ {
166
+ diff: [
167
+ "diff --git a/file.txt b/file.txt",
168
+ "index abc123..def456 100644",
169
+ "--- a/file.txt",
170
+ "+++ b/file.txt",
171
+ ].join("\n"),
172
+ },
173
+ { expanded: true },
174
+ defaultConfig as any,
175
+ passThroughTheme,
176
+ "",
177
+ );
178
+ const lines = renderInsideToolBox(component, 80);
179
+ // Should render with 0 added/0 removed
180
+ assert.ok(lines.length > 0);
181
+ });
182
+
183
+ test("renderEditDiffResult handles empty diff with fallback text", () => {
184
+ const component = renderEditDiffResult(
185
+ { diff: "" },
186
+ { expanded: true },
187
+ defaultConfig as any,
188
+ passThroughTheme,
189
+ "↳ file updated",
190
+ );
191
+ const lines = renderInsideToolBox(component, 80);
192
+ assert.ok(lines.some((line) => line.includes("file updated")));
193
+ });
194
+
195
+ // ─── Malformed diff input ──────────────────────────────────────────────────
196
+
197
+ test("renderEditDiffResult handles undefined diff in details", () => {
198
+ const component = renderEditDiffResult(
199
+ {},
200
+ { expanded: true },
201
+ defaultConfig as any,
202
+ passThroughTheme,
203
+ "",
204
+ );
205
+ const lines = renderInsideToolBox(component, 80);
206
+ assert.ok(lines.length > 0);
207
+ assert.ok(lines.some((line) => line.includes("no diff payload")));
208
+ });
209
+
210
+ test("renderEditDiffResult handles null details", () => {
211
+ const component = renderEditDiffResult(
212
+ null,
213
+ { expanded: true },
214
+ defaultConfig as any,
215
+ passThroughTheme,
216
+ "",
217
+ );
218
+ const lines = renderInsideToolBox(component, 80);
219
+ assert.ok(lines.length > 0);
220
+ });
221
+
222
+ test("renderEditDiffResult handles non-object details", () => {
223
+ // string instead of object
224
+ const component = renderEditDiffResult(
225
+ "not an object" as any,
226
+ { expanded: true },
227
+ defaultConfig as any,
228
+ passThroughTheme,
229
+ "",
230
+ );
231
+ const lines = renderInsideToolBox(component, 80);
232
+ assert.ok(lines.length > 0);
233
+ });
234
+
235
+ test("renderEditDiffResult handles array as details", () => {
236
+ const component = renderEditDiffResult(
237
+ [] as any,
238
+ { expanded: true },
239
+ defaultConfig as any,
240
+ passThroughTheme,
241
+ "",
242
+ );
243
+ const lines = renderInsideToolBox(component, 80);
244
+ assert.ok(lines.length > 0);
245
+ });
246
+
247
+ test("renderEditDiffResult handles diff property with non-string value", () => {
248
+ const component = renderEditDiffResult(
249
+ { diff: 42 },
250
+ { expanded: true },
251
+ defaultConfig as any,
252
+ passThroughTheme,
253
+ "",
254
+ );
255
+ const lines = renderInsideToolBox(component, 80);
256
+ // safeGetDiff would return "" for non-string diff
257
+ assert.ok(lines.some((line) => line.includes("no diff payload")));
258
+ });
259
+
260
+ test("renderEditDiffResult handles git binary diff patch gracefully", () => {
261
+ const binaryDiff = [
262
+ "diff --git a/image.png b/image.png",
263
+ "index abc..def 100644",
264
+ "Binary files a/image.png and b/image.png differ",
265
+ ].join("\n");
266
+ const component = renderEditDiffResult(
267
+ { diff: binaryDiff },
268
+ { expanded: true, filePath: "image.png" },
269
+ defaultConfig as any,
270
+ passThroughTheme,
271
+ "",
272
+ );
273
+ const lines = renderInsideToolBox(component, 80);
274
+ // Should render without crashing (binary diff lines are treated as meta/context)
275
+ assert.ok(lines.length > 0);
276
+ });
277
+
278
+ // ─── Diff with unicode, BOM, CRLF ──────────────────────────────────────────
279
+
280
+ test("renderEditDiffResult renders diff with unicode characters", () => {
281
+ const diff = [
282
+ "--- a/unicode.txt",
283
+ "+++ b/unicode.txt",
284
+ "@@ -1 +1 @@",
285
+ "-hello",
286
+ "+héllo wörld 你好 🎉",
287
+ ].join("\n");
288
+ const component = renderEditDiffResult(
289
+ { diff },
290
+ { expanded: true, filePath: "unicode.txt" },
291
+ defaultConfig as any,
292
+ passThroughTheme,
293
+ "",
294
+ );
295
+ const lines = renderInsideToolBox(component, 80);
296
+ assert.ok(lines.length > 0);
297
+ const joined = lines.join("");
298
+ assert.ok(joined.includes("héllo") || joined.includes("hello"));
299
+ });
300
+
301
+ test("renderEditDiffResult renders diff with BOM prefix gracefully", () => {
302
+ const diff = "\uFEFF--- a/bom.txt\n+++ b/bom.txt\n@@ -1 +1 @@\n-old\n+new\n";
303
+ const component = renderEditDiffResult(
304
+ { diff },
305
+ { expanded: true, filePath: "bom.txt" },
306
+ defaultConfig as any,
307
+ passThroughTheme,
308
+ "",
309
+ );
310
+ const lines = renderInsideToolBox(component, 80);
311
+ // BOM is data before diff markers; parseDiff should handle it or not crash
312
+ assert.ok(lines.length > 0);
313
+ });
314
+
315
+ test("renderEditDiffResult handles CRLF line endings in diff", () => {
316
+ const diff = "--- a/crlf.txt\r\n+++ b/crlf.txt\r\n@@ -1 +1 @@\r\n-old line\r\n+new line\r\n";
317
+ const component = renderEditDiffResult(
318
+ { diff },
319
+ { expanded: true, filePath: "crlf.txt" },
320
+ defaultConfig as any,
321
+ passThroughTheme,
322
+ "",
323
+ );
324
+ const lines = renderInsideToolBox(component, 80);
325
+ assert.ok(lines.length > 0);
326
+ });
327
+
328
+ test("renderEditDiffResult renders diff with mixed indentation (tabs, spaces)", () => {
329
+ const diff = [
330
+ "--- a/file.txt",
331
+ "+++ b/file.txt",
332
+ "@@ -1,3 +1,3 @@",
333
+ "- indented",
334
+ "- tabbed",
335
+ "+\t\t changed",
336
+ "+\t\t path",
337
+ "",
338
+ ].join("\n");
339
+ const component = renderEditDiffResult(
340
+ { diff },
341
+ { expanded: true, filePath: "file.txt" },
342
+ defaultConfig as any,
343
+ passThroughTheme,
344
+ "",
345
+ );
346
+ const lines = renderInsideToolBox(component, 80);
347
+ assert.ok(lines.length > 0);
348
+ });
349
+
350
+ // ─── Split diff when canRenderSplitLayout is false ─────────────────────────
351
+
352
+ test("renderEditDiffResult falls back to unified when split layout cannot render", () => {
353
+ // Width 40 is below 51 (2*24 + 3), so canRenderSplitLayout returns false.
354
+ // resolveDiffPresentationMode with diffViewMode="split" returns "unified"
355
+ const diff = [
356
+ "--- a/demo.ts",
357
+ "+++ b/demo.ts",
358
+ "@@ -1,3 +1,4 @@",
359
+ " const a = 1;",
360
+ "-const b = 2;",
361
+ "+const b = 42;",
362
+ " const c = 3;",
363
+ "+const d = 4;",
364
+ ].join("\n");
365
+ const component = renderEditDiffResult(
366
+ { diff },
367
+ { expanded: true, filePath: "demo.ts" },
368
+ {
369
+ ...defaultConfig,
370
+ diffViewMode: "split",
371
+ } as any,
372
+ passThroughTheme,
373
+ "",
374
+ );
375
+ const lines = renderInsideToolBox(component, 40);
376
+ // Should render without crash, showing unified view
377
+ assert.ok(lines.length > 0);
378
+ // In split mode top border shows "─┬─"; unified doesn't use that
379
+ const joined = lines.join("");
380
+ assert.ok(
381
+ !joined.includes("─┬─"),
382
+ `Split top border should not appear in unified fallback: ${joined}`,
383
+ );
384
+ });
385
+
386
+ test("renderEditDiffResult narrow width auto mode falls back from split to unified", () => {
387
+ const diff = [
388
+ "--- a/a.ts",
389
+ "+++ b/a.ts",
390
+ "@@ -1 +1 @@",
391
+ "-old",
392
+ "+new",
393
+ ].join("\n");
394
+ const component = renderEditDiffResult(
395
+ { diff },
396
+ { expanded: true, filePath: "a.ts" },
397
+ {
398
+ diffViewMode: "auto",
399
+ diffSplitMinWidth: 200, // Requires 200+ width for split
400
+ diffCollapsedLines: 24,
401
+ diffWordWrap: false,
402
+ } as any,
403
+ passThroughTheme,
404
+ "",
405
+ );
406
+ const lines = renderInsideToolBox(component, 80);
407
+ assert.ok(lines.length > 0);
408
+ });
409
+
410
+ // ─── Syntax highlighting failure ───────────────────────────────────────────
411
+
412
+ test("renderEditDiffResult handles unknown language gracefully", () => {
413
+ const diff = [
414
+ "--- a/file.unknown_extension_xyz",
415
+ "+++ b/file.unknown_extension_xyz",
416
+ "@@ -1 +1 @@",
417
+ "-print('hello');",
418
+ "+print('world');",
419
+ ].join("\n");
420
+ const component = renderEditDiffResult(
421
+ { diff },
422
+ { expanded: true, filePath: "file.unknown_extension_xyz" },
423
+ defaultConfig as any,
424
+ passThroughTheme,
425
+ "",
426
+ );
427
+ const lines = renderInsideToolBox(component, 80);
428
+ assert.ok(lines.length > 0);
429
+ });
430
+
431
+ test("renderEditDiffResult handles null filePath (no highlighting attempted)", () => {
432
+ const diff = [
433
+ "--- a/f.txt",
434
+ "+++ b/f.txt",
435
+ "@@ -1 +1 @@",
436
+ "-old content",
437
+ "+new content",
438
+ ].join("\n");
439
+ const component = renderEditDiffResult(
440
+ { diff },
441
+ { expanded: true, filePath: undefined },
442
+ defaultConfig as any,
443
+ passThroughTheme,
444
+ "",
445
+ );
446
+ const lines = renderInsideToolBox(component, 80);
447
+ assert.ok(lines.length > 0);
448
+ });
449
+
450
+ test("renderEditDiffResult handles empty filePath string", () => {
451
+ const diff = [
452
+ "--- a/f.txt",
453
+ "+++ b/f.txt",
454
+ "@@ -1 +1 @@",
455
+ "-a",
456
+ "+b",
457
+ ].join("\n");
458
+ const component = renderEditDiffResult(
459
+ { diff },
460
+ { expanded: true, filePath: "" },
461
+ defaultConfig as any,
462
+ passThroughTheme,
463
+ "",
464
+ );
465
+ const lines = renderInsideToolBox(component, 80);
466
+ assert.ok(lines.length > 0);
467
+ });
468
+
469
+ // ─── Large overwrite guard behavior in write diffs ──────────────────────────
470
+
471
+ test("renderWriteDiffResult triggers overwrite guard when previousLineCount * nextLineCount exceeds matrix limit", () => {
472
+ // Matrix limit is 1,000,000 cells. Using 1001 previous lines × 1000 next lines = 1,001,000 > 1M.
473
+ const previousLines = Array.from({ length: 1001 }, (_, i) => `previous line ${i}`);
474
+ const nextLines = Array.from({ length: 1000 }, (_, i) => `next line ${i}`);
475
+ const previousContent = previousLines.join("\n");
476
+ const content = nextLines.join("\n");
477
+
478
+ const component = renderWriteDiffResult(
479
+ content,
480
+ {
481
+ expanded: true,
482
+ filePath: "large.txt",
483
+ previousContent,
484
+ fileExistedBeforeWrite: true,
485
+ },
486
+ defaultConfig as any,
487
+ passThroughTheme,
488
+ "",
489
+ );
490
+ const lines = renderInsideToolBox(component, 80);
491
+ assert.ok(lines.length > 0);
492
+ const joined = lines.join("");
493
+ assert.ok(
494
+ joined.includes("overwrite diff omitted") || joined.includes("large"),
495
+ `Expected overwrite guard message in output: ${joined}`,
496
+ );
497
+ });
498
+
499
+ test("renderWriteDiffResult triggers guard when previous lines exceed MAX_WRITE_OVERWRITE_LINES", () => {
500
+ // MAX_WRITE_OVERWRITE_DIFF_LINES = 4000
501
+ const previousLines = Array.from({ length: 4001 }, (_, i) => `line ${i}`);
502
+ const nextLines = ["single line"];
503
+ const previousContent = previousLines.join("\n");
504
+
505
+ const component = renderWriteDiffResult(
506
+ "single line",
507
+ {
508
+ expanded: true,
509
+ filePath: "big.txt",
510
+ previousContent,
511
+ fileExistedBeforeWrite: true,
512
+ },
513
+ defaultConfig as any,
514
+ passThroughTheme,
515
+ "",
516
+ );
517
+ const lines = renderInsideToolBox(component, 80);
518
+ assert.ok(lines.length > 0);
519
+ });
520
+
521
+ test("renderWriteDiffResult does not trigger guard for small diffs", () => {
522
+ const previousContent = "line1\nline2\nline3";
523
+ const component = renderWriteDiffResult(
524
+ "line1\nline2\nline3\nline4",
525
+ {
526
+ expanded: true,
527
+ filePath: "small.txt",
528
+ previousContent,
529
+ fileExistedBeforeWrite: true,
530
+ },
531
+ defaultConfig as any,
532
+ passThroughTheme,
533
+ "",
534
+ );
535
+ const lines = renderInsideToolBox(component, 80);
536
+ assert.ok(lines.length > 0);
537
+ const joined = lines.join("");
538
+ assert.ok(
539
+ !joined.includes("overwrite diff omitted"),
540
+ `Small diff should not trigger overwrite guard: ${joined}`,
541
+ );
542
+ });
543
+
544
+ test("renderWriteDiffResult does not trigger guard for new file (not overwrite)", () => {
545
+ // fileExistedBeforeWrite is false, so guard is skipped
546
+ const component = renderWriteDiffResult(
547
+ "hello\nworld",
548
+ {
549
+ expanded: true,
550
+ filePath: "new.txt",
551
+ previousContent: undefined,
552
+ fileExistedBeforeWrite: false,
553
+ },
554
+ defaultConfig as any,
555
+ passThroughTheme,
556
+ "",
557
+ );
558
+ const lines = renderInsideToolBox(component, 80);
559
+ assert.ok(lines.length > 0);
560
+ });
561
+
562
+ test("renderWriteDiffResult reports created file header", () => {
563
+ const component = renderWriteDiffResult(
564
+ "new content",
565
+ {
566
+ expanded: true,
567
+ filePath: "fresh.txt",
568
+ fileExistedBeforeWrite: false,
569
+ },
570
+ defaultConfig as any,
571
+ passThroughTheme,
572
+ "",
573
+ );
574
+ const lines = renderInsideToolBox(component, 80);
575
+ const joined = lines.join("");
576
+ assert.ok(joined.includes("created") || joined.includes("↳"));
577
+ });
578
+
579
+ test("renderWriteDiffResult reports overwritten file header", () => {
580
+ const component = renderWriteDiffResult(
581
+ "new",
582
+ {
583
+ expanded: true,
584
+ filePath: "over.txt",
585
+ previousContent: "old",
586
+ fileExistedBeforeWrite: true,
587
+ },
588
+ defaultConfig as any,
589
+ passThroughTheme,
590
+ "",
591
+ );
592
+ const lines = renderInsideToolBox(component, 80);
593
+ const joined = lines.join("");
594
+ assert.ok(joined.includes("overwritten") || joined.includes("↳"));
595
+ });
596
+
597
+ // ─── renderWriteDiffResult with undefined / null content ────────────────────
598
+
599
+ test("renderWriteDiffResult handles undefined content", () => {
600
+ const component = renderWriteDiffResult(
601
+ undefined,
602
+ { expanded: true, filePath: "f.txt" },
603
+ defaultConfig as any,
604
+ passThroughTheme,
605
+ "",
606
+ );
607
+ const lines = renderInsideToolBox(component, 80);
608
+ assert.ok(lines.some((l) => l.includes("write completed")));
609
+ });
610
+
611
+ test("renderWriteDiffResult handles non-string content", () => {
612
+ const component = renderWriteDiffResult(
613
+ 42 as any,
614
+ { expanded: true, filePath: "f.txt" },
615
+ defaultConfig as any,
616
+ passThroughTheme,
617
+ "",
618
+ );
619
+ const lines = renderInsideToolBox(component, 80);
620
+ assert.ok(lines.some((l) => l.includes("write completed")));
621
+ });
622
+
623
+ test("renderWriteDiffResult uses fallback text when content is missing", () => {
624
+ const component = renderWriteDiffResult(
625
+ undefined,
626
+ { expanded: true, filePath: "f.txt" },
627
+ defaultConfig as any,
628
+ passThroughTheme,
629
+ "↳ file saved successfully",
630
+ );
631
+ const lines = renderInsideToolBox(component, 80);
632
+ assert.ok(lines.some((l) => l.includes("saved successfully")));
633
+ });
634
+
635
+ // ─── renderEditDiffResult with very narrow widths ──────────────────────────
636
+
637
+ test("renderEditDiffResult renders summary at very narrow width", () => {
638
+ const diff = [
639
+ "--- a/a.ts",
640
+ "+++ b/a.ts",
641
+ "@@ -1,2 +1,2 @@",
642
+ "-old1",
643
+ "-old2",
644
+ "+new1",
645
+ "+new2",
646
+ ].join("\n");
647
+ const component = renderEditDiffResult(
648
+ { diff },
649
+ { expanded: true, filePath: "a.ts" },
650
+ defaultConfig as any,
651
+ passThroughTheme,
652
+ "",
653
+ );
654
+ const lines = renderInsideToolBox(component, 5);
655
+ assert.ok(lines.length > 0);
656
+ });
657
+
658
+ test("renderEditDiffResult renders compact mode at narrow width (8..17)", () => {
659
+ const diff = [
660
+ "--- a/a.ts",
661
+ "+++ b/a.ts",
662
+ "@@ -1 +1 @@",
663
+ "-old",
664
+ "+new",
665
+ ].join("\n");
666
+ const component = renderEditDiffResult(
667
+ { diff },
668
+ { expanded: true, filePath: "a.ts" },
669
+ defaultConfig as any,
670
+ passThroughTheme,
671
+ "",
672
+ );
673
+ const lines = renderInsideToolBox(component, 12);
674
+ assert.ok(lines.length > 0);
675
+ });
676
+
677
+ // ─── write diff with empty content ─────────────────────────────────────────
678
+
679
+ test("renderWriteDiffResult handles empty string content", () => {
680
+ const component = renderWriteDiffResult(
681
+ "",
682
+ { expanded: true, filePath: "empty.txt" },
683
+ defaultConfig as any,
684
+ passThroughTheme,
685
+ "",
686
+ );
687
+ const lines = renderInsideToolBox(component, 80);
688
+ assert.ok(lines.length > 0);
689
+ });
690
+
691
+ test("renderWriteDiffResult handles overwrite with identical content", () => {
692
+ const previousContent = "same\ncontent";
693
+ const component = renderWriteDiffResult(
694
+ "same\ncontent",
695
+ {
696
+ expanded: true,
697
+ filePath: "same.txt",
698
+ previousContent,
699
+ fileExistedBeforeWrite: true,
700
+ },
701
+ defaultConfig as any,
702
+ passThroughTheme,
703
+ "",
704
+ );
705
+ const lines = renderInsideToolBox(component, 80);
706
+ assert.ok(lines.length > 0);
707
+ });
708
+
709
+ // ─── Edit diff with hashline anchors (canonical format) ─────────────────────
710
+
711
+ test("renderEditDiffResult renders canonical numbered diff with hashline anchors", () => {
712
+ const diff = [
713
+ " 1|import { foo } from './foo';",
714
+ "- 2|const oldVar = true;",
715
+ "+ 2|const newVar = true;",
716
+ " 3|export function test() {",
717
+ ].join("\n");
718
+ const component = renderEditDiffResult(
719
+ { diff },
720
+ { expanded: true, filePath: "demo.ts" },
721
+ defaultConfig as any,
722
+ passThroughTheme,
723
+ "",
724
+ );
725
+ const lines = renderInsideToolBox(component, 80);
726
+ assert.ok(lines.length > 0);
727
+ });
728
+
729
+ // ─── edit diff with only context lines ─────────────────────────────────────
730
+
731
+ test("renderEditDiffResult handles diff with only context lines", () => {
732
+ const diff = [
733
+ "--- a/ctx.txt",
734
+ "+++ b/ctx.txt",
735
+ "@@ -1,3 +1,3 @@",
736
+ " unchanged1",
737
+ " unchanged2",
738
+ " unchanged3",
739
+ ].join("\n");
740
+ const component = renderEditDiffResult(
741
+ { diff },
742
+ { expanded: true, filePath: "ctx.txt" },
743
+ defaultConfig as any,
744
+ passThroughTheme,
745
+ "",
746
+ );
747
+ const lines = renderInsideToolBox(component, 80);
748
+ assert.ok(lines.length > 0);
749
+ });
750
+
751
+ // ─── resolveDiffPresentationMode with explicit diffSplitMinWidth extremes ───
752
+
753
+ test("resolveDiffPresentationMode honors large diffSplitMinWidth for auto mode", () => {
754
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 9999 };
755
+ // Width 1000 < 9999, so returns "unified"
756
+ assert.equal(resolveDiffPresentationMode(config, 1000, true), "unified");
757
+ // Width 10000 >= 9999, returns "split"
758
+ assert.equal(resolveDiffPresentationMode(config, 10000, true), "split");
759
+ });
760
+
761
+ test("resolveDiffPresentationMode honors zero diffSplitMinWidth", () => {
762
+ // With diffSplitMinWidth = 0, auto mode always qualifies for split if canRenderSplitLayout
763
+ const config = { diffViewMode: "auto" as const, diffSplitMinWidth: 0 };
764
+ assert.equal(resolveDiffPresentationMode(config, 51, true), "split");
765
+ });
766
+
767
+ // ─── buildDiffSummaryText edge cases ───────────────────────────────────────
768
+
769
+ test("buildDiffSummaryText returns empty string for zero width", () => {
770
+ const stats = { added: 5, removed: 3, hunks: 2, files: 1 };
771
+ assert.equal(buildDiffSummaryText(stats, 0), "");
772
+ });
773
+
774
+ test("buildDiffSummaryText returns empty string for negative width", () => {
775
+ const stats = { added: 5, removed: 3, hunks: 2, files: 1 };
776
+ assert.equal(buildDiffSummaryText(stats, -1), "");
777
+ });
778
+
779
+ test("buildDiffSummaryText returns minimal text for very narrow width", () => {
780
+ const stats = { added: 10, removed: 5, hunks: 3, files: 2 };
781
+ const result = buildDiffSummaryText(stats, 1);
782
+ assert.equal(result, "…");
783
+ });
784
+
785
+ test("buildDiffSummaryText returns progressively shorter candidates for limited width", () => {
786
+ const stats = { added: 100, removed: 50, hunks: 5, files: 3 };
787
+ // Narrow but not too narrow
788
+ const narrow = buildDiffSummaryText(stats, 10);
789
+ assert.ok(typeof narrow === "string");
790
+ assert.ok(narrow.length <= 10);
791
+
792
+ const medium = buildDiffSummaryText(stats, 30);
793
+ assert.ok(medium.length > 0);
794
+
795
+ const wide = buildDiffSummaryText(stats, 120);
796
+ assert.ok(wide.startsWith("↳ diff"));
797
+ });
798
+
799
+ test("buildDiffSummaryText handles zero stats", () => {
800
+ const stats = { added: 0, removed: 0, hunks: 0, files: 0 };
801
+ const result = buildDiffSummaryText(stats, 80);
802
+ // With zero stats, the first candidate "↳ diff +0 -0 • 0 hunks • 0 files" fits
803
+ assert.ok(result.includes("+0"));
804
+ assert.ok(result.includes("-0"));
805
+ });
806
+
807
+ // ─── renderWriteDiffResult with custom header label ────────────────────────
808
+
809
+ test("renderWriteDiffResult uses custom header label", () => {
810
+ const component = renderWriteDiffResult(
811
+ "content",
812
+ {
813
+ expanded: true,
814
+ filePath: "custom.txt",
815
+ headerLabel: "custom-label",
816
+ fileExistedBeforeWrite: false,
817
+ },
818
+ defaultConfig as any,
819
+ passThroughTheme,
820
+ "",
821
+ );
822
+ const lines = renderInsideToolBox(component, 80);
823
+ const joined = lines.join("");
824
+ assert.ok(joined.includes("custom-label"), `Expected custom label in output: ${joined}`);
825
+ });
826
+
827
+ test("renderWriteDiffResult falls back to 'created' when no header label for new file", () => {
828
+ const component = renderWriteDiffResult(
829
+ "content",
830
+ {
831
+ expanded: true,
832
+ filePath: "nothdr.txt",
833
+ fileExistedBeforeWrite: false,
834
+ },
835
+ defaultConfig as any,
836
+ passThroughTheme,
837
+ "",
838
+ );
839
+ const lines = renderInsideToolBox(component, 80);
840
+ const joined = lines.join("");
841
+ assert.ok(joined.includes("created") || joined.includes("↳"));
842
+ });
843
+
844
+ // ─── renderEditDiffResult with summary mode at width 0 ────────────────────
845
+
846
+ test("renderEditDiffResult handles width 0 without crashing", () => {
847
+ const diff = [
848
+ "--- a/a.ts",
849
+ "+++ b/a.ts",
850
+ "@@ -1 +1 @@",
851
+ "-old",
852
+ "+new",
853
+ ].join("\n");
854
+ const component = renderEditDiffResult(
855
+ { diff },
856
+ { expanded: true, filePath: "a.ts" },
857
+ defaultConfig as any,
858
+ passThroughTheme,
859
+ "",
860
+ );
861
+ const lines = renderInsideToolBox(component, 0);
862
+ assert.ok(lines.length > 0);
863
+ });
864
+
865
+ test("renderEditDiffResult handles width 1 (minimum summary)", () => {
866
+ const diff = [
867
+ "--- a/a.ts",
868
+ "+++ b/a.ts",
869
+ "@@ -1,5 +1,5 @@",
870
+ " line1",
871
+ "-remove1",
872
+ "-remove2",
873
+ "+add1",
874
+ "+add2",
875
+ " line5",
876
+ ].join("\n");
877
+ const component = renderEditDiffResult(
878
+ { diff },
879
+ { expanded: true, filePath: "a.ts" },
880
+ defaultConfig as any,
881
+ passThroughTheme,
882
+ "",
883
+ );
884
+ const lines = renderInsideToolBox(component, 1);
885
+ assert.ok(lines.length > 0);
886
+ });