@selesai/code 0.10.2 → 0.11.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 (502) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cli/credential-print.js +4 -4
  3. package/dist/cli.js +0 -0
  4. package/dist/core/compaction/branch-summarization.js +30 -30
  5. package/dist/core/compaction/compaction.js +81 -81
  6. package/dist/core/compaction/utils.js +2 -2
  7. package/dist/core/export-html/template.css +1066 -1066
  8. package/dist/core/export-html/template.html +55 -55
  9. package/dist/core/export-html/template.js +1864 -1864
  10. package/dist/core/export-html/vendor/highlight.min.js +1212 -1212
  11. package/dist/core/export-html/vendor/marked.min.js +78 -78
  12. package/dist/core/messages.js +7 -7
  13. package/dist/defaults/settings.json +0 -3
  14. package/dist/extensions/auto-session-name.test.ts +157 -0
  15. package/dist/extensions/auto-session-name.ts +96 -0
  16. package/dist/extensions/context-compaction-reminder.test.ts +82 -82
  17. package/dist/extensions/context-compaction-reminder.ts +28 -28
  18. package/dist/extensions/cost-reconcile.test.ts +76 -0
  19. package/dist/extensions/cost-reconcile.ts +278 -0
  20. package/dist/extensions/enable-readonly-tools.test.ts +11 -0
  21. package/dist/extensions/enable-readonly-tools.ts +7 -3
  22. package/dist/extensions/package.json +3 -0
  23. package/dist/extensions/pi-intercom/LICENSE +21 -21
  24. package/dist/extensions/pi-intercom/broker/client.test.ts +83 -83
  25. package/dist/extensions/pi-intercom/broker/framing.test.ts +114 -114
  26. package/dist/extensions/pi-intercom/broker/paths.ts +134 -134
  27. package/dist/extensions/pi-intercom/broker/runtime-claim.test.ts +34 -34
  28. package/dist/extensions/pi-intercom/broker/runtime-claim.ts +21 -21
  29. package/dist/extensions/pi-intercom/cwd.test.ts +40 -40
  30. package/dist/extensions/pi-intercom/cwd.ts +31 -31
  31. package/dist/extensions/pi-intercom/format-context.test.ts +31 -31
  32. package/dist/extensions/pi-intercom/format-context.ts +32 -32
  33. package/dist/extensions/pi-intercom/test/overlay-width.test.ts +66 -66
  34. package/dist/extensions/pi-intercom/ui/compose.ts +143 -143
  35. package/dist/extensions/pi-intercom/ui/session-list.ts +166 -166
  36. package/dist/extensions/pi-rewind-hook/README.md +245 -245
  37. package/dist/extensions/pi-rewind-hook/index.ts +1445 -1445
  38. package/dist/extensions/pi-rewind-hook/package.json +29 -29
  39. package/dist/extensions/pi-subagents/install.mjs +0 -0
  40. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  41. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  42. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  43. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  44. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  45. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  46. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  47. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  48. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  49. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  50. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  51. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  52. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  53. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  54. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  55. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  56. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  57. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  58. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  59. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  60. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  61. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  62. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  63. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  64. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  65. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  66. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  67. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  68. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  69. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  70. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  71. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  72. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  73. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  74. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  75. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  76. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  77. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  78. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  79. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  80. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  81. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  82. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  83. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  84. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  85. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  86. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  87. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  88. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  89. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  90. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  91. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  92. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  93. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  94. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  95. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  96. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  97. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  98. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  99. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  100. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  101. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  102. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  103. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  104. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  105. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  106. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  107. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  108. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  109. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  110. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  111. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  112. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  113. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  114. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  115. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  116. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  117. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  118. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  119. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  120. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  121. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  122. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  123. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  124. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  125. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  126. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  127. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  128. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  129. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  130. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  131. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  132. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  133. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  134. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  135. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  136. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  137. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  138. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  139. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  140. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  141. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  142. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  143. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  144. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  145. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  146. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  147. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  148. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  149. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  150. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  151. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  152. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  153. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  154. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  155. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  156. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  157. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  158. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  159. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  160. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  161. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  162. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  163. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  164. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  165. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  166. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  167. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  168. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  169. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  170. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  171. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  172. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  173. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  174. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  175. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  176. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  177. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  178. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  179. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  180. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  181. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  182. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  183. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  184. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  215. package/dist/extensions/pi-tool-display/CHANGELOG.md +329 -0
  216. package/dist/extensions/pi-tool-display/LICENSE +21 -0
  217. package/dist/extensions/pi-tool-display/README.md +417 -0
  218. package/dist/extensions/pi-tool-display/config/config.example.json +40 -0
  219. package/dist/extensions/pi-tool-display/index.ts +3 -0
  220. package/dist/extensions/pi-tool-display/package-lock.json +2555 -0
  221. package/dist/extensions/pi-tool-display/package.json +86 -0
  222. package/dist/extensions/pi-tool-display/src/agent-dir.ts +35 -0
  223. package/dist/extensions/pi-tool-display/src/ansi-utils.ts +116 -0
  224. package/dist/extensions/pi-tool-display/src/bash-display.ts +213 -0
  225. package/dist/extensions/pi-tool-display/src/capabilities.ts +88 -0
  226. package/dist/extensions/pi-tool-display/src/config-modal.ts +541 -0
  227. package/dist/extensions/pi-tool-display/src/config-store.ts +304 -0
  228. package/dist/extensions/pi-tool-display/src/debug-logger.ts +150 -0
  229. package/dist/extensions/pi-tool-display/src/diff-presentation.ts +72 -0
  230. package/dist/extensions/pi-tool-display/src/diff-renderer.ts +2517 -0
  231. package/dist/extensions/pi-tool-display/src/disposable.ts +34 -0
  232. package/dist/extensions/pi-tool-display/src/extension-lifecycle.ts +14 -0
  233. package/dist/extensions/pi-tool-display/src/index.ts +109 -0
  234. package/dist/extensions/pi-tool-display/src/line-width-safety.ts +93 -0
  235. package/dist/extensions/pi-tool-display/src/modal-icons.ts +57 -0
  236. package/dist/extensions/pi-tool-display/src/pending-diff-preview.ts +370 -0
  237. package/dist/extensions/pi-tool-display/src/presets.ts +117 -0
  238. package/dist/extensions/pi-tool-display/src/render-utils.ts +186 -0
  239. package/dist/extensions/pi-tool-display/src/settings-inspector-modal.ts +475 -0
  240. package/dist/extensions/pi-tool-display/src/thinking-label.ts +343 -0
  241. package/dist/extensions/pi-tool-display/src/tool-call-box.ts +181 -0
  242. package/dist/extensions/pi-tool-display/src/tool-metadata.ts +139 -0
  243. package/dist/extensions/pi-tool-display/src/tool-overrides.ts +2168 -0
  244. package/dist/extensions/pi-tool-display/src/types.ts +109 -0
  245. package/dist/extensions/pi-tool-display/src/user-message-box-markdown.ts +64 -0
  246. package/dist/extensions/pi-tool-display/src/user-message-box-native.ts +66 -0
  247. package/dist/extensions/pi-tool-display/src/user-message-box-patch.ts +72 -0
  248. package/dist/extensions/pi-tool-display/src/user-message-box-renderer.ts +419 -0
  249. package/dist/extensions/pi-tool-display/src/user-message-box-utils.ts +106 -0
  250. package/dist/extensions/pi-tool-display/src/write-display-utils.ts +31 -0
  251. package/dist/extensions/pi-tool-display/src/zellij-modal.ts +1027 -0
  252. package/dist/extensions/pi-tool-display/tests/active-backlog-red.test.ts +65 -0
  253. package/dist/extensions/pi-tool-display/tests/ansi-utils.test.ts +345 -0
  254. package/dist/extensions/pi-tool-display/tests/bash-display.test.ts +442 -0
  255. package/dist/extensions/pi-tool-display/tests/capabilities-edge.test.ts +360 -0
  256. package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +54 -0
  257. package/dist/extensions/pi-tool-display/tests/config-modal.test.ts +360 -0
  258. package/dist/extensions/pi-tool-display/tests/config-store.test.ts +87 -0
  259. package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +415 -0
  260. package/dist/extensions/pi-tool-display/tests/debug-logger-edge.test.ts +630 -0
  261. package/dist/extensions/pi-tool-display/tests/debug-logger.test.ts +62 -0
  262. package/dist/extensions/pi-tool-display/tests/diff-renderer-ansi.test.ts +55 -0
  263. package/dist/extensions/pi-tool-display/tests/diff-renderer-edge.test.ts +886 -0
  264. package/dist/extensions/pi-tool-display/tests/diff-renderer-numbering.test.ts +135 -0
  265. package/dist/extensions/pi-tool-display/tests/diff-renderer-width.test.ts +454 -0
  266. package/dist/extensions/pi-tool-display/tests/diff-renderer-wrap.test.ts +169 -0
  267. package/dist/extensions/pi-tool-display/tests/index-integration.test.ts +354 -0
  268. package/dist/extensions/pi-tool-display/tests/pending-diff-preview.test.ts +79 -0
  269. package/dist/extensions/pi-tool-display/tests/presets-edge.test.ts +229 -0
  270. package/dist/extensions/pi-tool-display/tests/presets.test.ts +26 -0
  271. package/dist/extensions/pi-tool-display/tests/reload-behavior.test.ts +1241 -0
  272. package/dist/extensions/pi-tool-display/tests/render-utils.test.ts +710 -0
  273. package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +450 -0
  274. package/dist/extensions/pi-tool-display/tests/thinking-label-edge.test.ts +904 -0
  275. package/dist/extensions/pi-tool-display/tests/thinking-label.test.ts +72 -0
  276. package/dist/extensions/pi-tool-display/tests/tool-call-box.test.ts +105 -0
  277. package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +613 -0
  278. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +499 -0
  279. package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +315 -0
  280. package/dist/extensions/pi-tool-display/tests/tool-overrides-write-meta.test.ts +68 -0
  281. package/dist/extensions/pi-tool-display/tests/tool-ui-utils.test.ts +413 -0
  282. package/dist/extensions/pi-tool-display/tests/user-message-box-performance-red.test.ts +176 -0
  283. package/dist/extensions/pi-tool-display/tests/user-message-box.test.ts +908 -0
  284. package/dist/extensions/pi-tool-display/tests/zellij-modal.test.ts +848 -0
  285. package/dist/extensions/pi-tool-display/tool-display-api-consumer.d.ts +30 -0
  286. package/dist/extensions/pi-tool-display/tool-display-api-consumer.js +40 -0
  287. package/dist/extensions/pi-web-agent/package.json +31 -31
  288. package/dist/extensions/pi-web-agent/src/backends/config.ts +205 -205
  289. package/dist/extensions/pi-web-agent/src/backends/doctor.ts +136 -136
  290. package/dist/extensions/pi-web-agent/src/backends/factory.ts +152 -152
  291. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +25 -25
  292. package/dist/extensions/pi-web-agent/src/cache/ttl-cache.ts +28 -28
  293. package/dist/extensions/pi-web-agent/src/changelog-notice.ts +136 -136
  294. package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +946 -946
  295. package/dist/extensions/pi-web-agent/src/extension.ts +126 -126
  296. package/dist/extensions/pi-web-agent/src/extract/readability.ts +118 -118
  297. package/dist/extensions/pi-web-agent/src/fetch/browser-resolution.ts +199 -199
  298. package/dist/extensions/pi-web-agent/src/fetch/firecrawl-fetch.ts +100 -100
  299. package/dist/extensions/pi-web-agent/src/fetch/headless-fetch.ts +117 -117
  300. package/dist/extensions/pi-web-agent/src/fetch/http-fetch.ts +67 -67
  301. package/dist/extensions/pi-web-agent/src/orchestration/answer-synthesizer.ts +60 -60
  302. package/dist/extensions/pi-web-agent/src/orchestration/candidate-selector.ts +50 -50
  303. package/dist/extensions/pi-web-agent/src/orchestration/direct-url.ts +52 -52
  304. package/dist/extensions/pi-web-agent/src/orchestration/evidence-quality.ts +105 -105
  305. package/dist/extensions/pi-web-agent/src/orchestration/evidence-ranker.ts +45 -45
  306. package/dist/extensions/pi-web-agent/src/orchestration/index.ts +28 -28
  307. package/dist/extensions/pi-web-agent/src/orchestration/query-planner.ts +47 -47
  308. package/dist/extensions/pi-web-agent/src/orchestration/research-orchestrator.ts +376 -376
  309. package/dist/extensions/pi-web-agent/src/orchestration/research-types.ts +64 -64
  310. package/dist/extensions/pi-web-agent/src/orchestration/research-worker.ts +181 -181
  311. package/dist/extensions/pi-web-agent/src/orchestration/source-profile.ts +101 -101
  312. package/dist/extensions/pi-web-agent/src/orchestration/stop-decider.ts +81 -81
  313. package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +210 -210
  314. package/dist/extensions/pi-web-agent/src/presentation/config.ts +75 -75
  315. package/dist/extensions/pi-web-agent/src/presentation/explore-presentation.ts +61 -61
  316. package/dist/extensions/pi-web-agent/src/presentation/fetch-presentation.ts +54 -54
  317. package/dist/extensions/pi-web-agent/src/presentation/search-presentation.ts +41 -41
  318. package/dist/extensions/pi-web-agent/src/presentation/select-view.ts +20 -20
  319. package/dist/extensions/pi-web-agent/src/presentation/types.ts +63 -63
  320. package/dist/extensions/pi-web-agent/src/search/brave.ts +114 -114
  321. package/dist/extensions/pi-web-agent/src/search/duckduckgo.ts +72 -72
  322. package/dist/extensions/pi-web-agent/src/search/searxng.ts +96 -96
  323. package/dist/extensions/pi-web-agent/src/tools/web-explore.ts +71 -71
  324. package/dist/extensions/pi-web-agent/src/tools/web-fetch-headless.ts +31 -31
  325. package/dist/extensions/pi-web-agent/src/tools/web-fetch.ts +31 -31
  326. package/dist/extensions/pi-web-agent/src/tools/web-search.ts +157 -157
  327. package/dist/extensions/pi-web-agent/src/types.ts +88 -88
  328. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +46 -1
  329. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +10 -0
  330. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +1 -1
  331. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +3 -3
  332. package/dist/extensions/pi-zentui/test/format.test.ts +50 -2
  333. package/dist/extensions/ponytail/package.json +8 -8
  334. package/dist/extensions/question/constants.ts +30 -30
  335. package/dist/extensions/question/helpers.ts +58 -58
  336. package/dist/extensions/question/navigation.ts +14 -14
  337. package/dist/extensions/question/package.json +19 -19
  338. package/dist/extensions/question/selection-mode.ts +46 -46
  339. package/dist/extensions/question/shortcuts.ts +44 -44
  340. package/dist/extensions/question/types.ts +132 -132
  341. package/dist/extensions/test-resolve-hook-impl.mjs +6 -6
  342. package/dist/extensions/test-resolve-hook.mjs +6 -6
  343. package/dist/extensions/web-agent-onboarding.ts +222 -222
  344. package/dist/modes/interactive/interactive-mode.js +17 -3
  345. package/dist/package-manager-cli.js +71 -71
  346. package/dist/rpc-entry.js +0 -0
  347. package/dist/skills/improve-codebase/REFERENCE.md +78 -78
  348. package/docs/compaction.md +396 -396
  349. package/docs/containerization.md +111 -111
  350. package/docs/development.md +71 -71
  351. package/docs/docs.json +164 -164
  352. package/docs/environment-variables.md +86 -86
  353. package/docs/index.md +83 -83
  354. package/docs/json.md +82 -82
  355. package/docs/models.md +502 -502
  356. package/docs/packages.md +227 -227
  357. package/docs/plans/subagent-delegation/phase-0-correctness.md +264 -264
  358. package/docs/plans/subagent-delegation/phase-1-behavioral-contract.md +485 -485
  359. package/docs/plans/subagent-delegation/phase-2-context-controls.md +281 -281
  360. package/docs/plans/subagent-delegation/phase-3-advisory-routing.md +361 -361
  361. package/docs/plans/subagent-delegation/phase-4-optional-enforcement.md +380 -380
  362. package/docs/prompt-templates.md +95 -95
  363. package/docs/providers.md +293 -293
  364. package/docs/security.md +59 -59
  365. package/docs/session-format.md +414 -414
  366. package/docs/sessions.md +145 -145
  367. package/docs/shared-host-extensions.md +109 -109
  368. package/docs/shell-aliases.md +13 -13
  369. package/docs/skills.md +231 -231
  370. package/docs/terminal-setup.md +142 -142
  371. package/docs/termux.md +127 -127
  372. package/docs/themes.md +295 -295
  373. package/docs/tmux.md +63 -63
  374. package/docs/tui.md +927 -927
  375. package/docs/windows.md +17 -17
  376. package/examples/README.md +25 -25
  377. package/examples/extensions/README.md +211 -211
  378. package/examples/extensions/auto-commit-on-exit.ts +49 -49
  379. package/examples/extensions/bash-spawn-hook.ts +30 -30
  380. package/examples/extensions/bookmark.ts +50 -50
  381. package/examples/extensions/border-status-editor.ts +150 -150
  382. package/examples/extensions/built-in-tool-renderer.ts +249 -249
  383. package/examples/extensions/claude-rules.ts +86 -86
  384. package/examples/extensions/commands.ts +72 -72
  385. package/examples/extensions/confirm-destructive.ts +59 -59
  386. package/examples/extensions/custom-compaction.ts +130 -130
  387. package/examples/extensions/custom-footer.ts +64 -64
  388. package/examples/extensions/custom-header.ts +73 -73
  389. package/examples/extensions/custom-provider-anthropic/index.ts +610 -610
  390. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -24
  391. package/examples/extensions/custom-provider-anthropic/package.json +19 -19
  392. package/examples/extensions/custom-provider-gitlab-duo/index.ts +404 -404
  393. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -16
  394. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -82
  395. package/examples/extensions/dirty-repo-guard.ts +56 -56
  396. package/examples/extensions/doom-overlay/README.md +46 -46
  397. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -21
  398. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  399. package/examples/extensions/doom-overlay/doom/build.sh +152 -152
  400. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -72
  401. package/examples/extensions/doom-overlay/doom-component.ts +132 -132
  402. package/examples/extensions/doom-overlay/doom-engine.ts +173 -173
  403. package/examples/extensions/doom-overlay/doom-keys.ts +104 -104
  404. package/examples/extensions/doom-overlay/index.ts +74 -74
  405. package/examples/extensions/doom-overlay/wad-finder.ts +51 -51
  406. package/examples/extensions/dynamic-resources/SKILL.md +8 -8
  407. package/examples/extensions/dynamic-resources/dynamic.json +79 -79
  408. package/examples/extensions/dynamic-resources/dynamic.md +5 -5
  409. package/examples/extensions/dynamic-resources/index.ts +15 -15
  410. package/examples/extensions/dynamic-tools.ts +74 -74
  411. package/examples/extensions/event-bus.ts +43 -43
  412. package/examples/extensions/file-trigger.ts +41 -41
  413. package/examples/extensions/git-checkpoint.ts +53 -53
  414. package/examples/extensions/git-merge-and-resolve.ts +115 -115
  415. package/examples/extensions/github-issue-autocomplete.ts +185 -185
  416. package/examples/extensions/gondolin/index.ts +531 -531
  417. package/examples/extensions/gondolin/package-lock.json +185 -185
  418. package/examples/extensions/gondolin/package.json +19 -19
  419. package/examples/extensions/handoff.ts +199 -199
  420. package/examples/extensions/hello.ts +26 -26
  421. package/examples/extensions/hidden-thinking-label.ts +53 -53
  422. package/examples/extensions/inline-bash.ts +94 -94
  423. package/examples/extensions/input-transform-streaming.ts +39 -39
  424. package/examples/extensions/input-transform.ts +43 -43
  425. package/examples/extensions/interactive-shell.ts +196 -196
  426. package/examples/extensions/mac-system-theme.ts +47 -47
  427. package/examples/extensions/message-renderer.ts +59 -59
  428. package/examples/extensions/minimal-mode.ts +426 -426
  429. package/examples/extensions/modal-editor.ts +85 -85
  430. package/examples/extensions/model-status.ts +31 -31
  431. package/examples/extensions/notify.ts +55 -55
  432. package/examples/extensions/overlay-qa-tests.ts +1450 -1450
  433. package/examples/extensions/overlay-test.ts +153 -153
  434. package/examples/extensions/permission-gate.ts +34 -34
  435. package/examples/extensions/pirate.ts +47 -47
  436. package/examples/extensions/plan-mode/README.md +66 -66
  437. package/examples/extensions/plan-mode/index.ts +390 -390
  438. package/examples/extensions/plan-mode/utils.ts +168 -168
  439. package/examples/extensions/preset.ts +436 -436
  440. package/examples/extensions/project-trust.ts +64 -64
  441. package/examples/extensions/prompt-customizer.ts +97 -97
  442. package/examples/extensions/protected-paths.ts +30 -30
  443. package/examples/extensions/provider-payload.ts +18 -18
  444. package/examples/extensions/qna.ts +122 -122
  445. package/examples/extensions/question.ts +285 -285
  446. package/examples/extensions/questionnaire.ts +448 -448
  447. package/examples/extensions/rainbow-editor.ts +88 -88
  448. package/examples/extensions/reload-runtime.ts +37 -37
  449. package/examples/extensions/rpc-demo.ts +118 -118
  450. package/examples/extensions/sandbox/index.ts +321 -321
  451. package/examples/extensions/sandbox/package-lock.json +92 -92
  452. package/examples/extensions/sandbox/package.json +19 -19
  453. package/examples/extensions/send-user-message.ts +97 -97
  454. package/examples/extensions/session-name.ts +27 -27
  455. package/examples/extensions/shutdown-command.ts +63 -63
  456. package/examples/extensions/snake.ts +343 -343
  457. package/examples/extensions/space-invaders.ts +560 -560
  458. package/examples/extensions/ssh.ts +220 -220
  459. package/examples/extensions/status-line.ts +32 -32
  460. package/examples/extensions/structured-output.ts +65 -65
  461. package/examples/extensions/subagent/README.md +175 -175
  462. package/examples/extensions/subagent/agents/planner.md +37 -37
  463. package/examples/extensions/subagent/agents/reviewer.md +35 -35
  464. package/examples/extensions/subagent/agents/scout.md +50 -50
  465. package/examples/extensions/subagent/agents/worker.md +24 -24
  466. package/examples/extensions/subagent/agents.ts +126 -126
  467. package/examples/extensions/subagent/index.ts +1015 -1015
  468. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -10
  469. package/examples/extensions/subagent/prompts/implement.md +10 -10
  470. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -9
  471. package/examples/extensions/summarize.ts +209 -209
  472. package/examples/extensions/system-prompt-header.ts +17 -17
  473. package/examples/extensions/tic-tac-toe.ts +1008 -1008
  474. package/examples/extensions/timed-confirm.ts +70 -70
  475. package/examples/extensions/titlebar-spinner.ts +58 -58
  476. package/examples/extensions/todo.ts +297 -297
  477. package/examples/extensions/tool-override.ts +144 -144
  478. package/examples/extensions/tools.ts +146 -146
  479. package/examples/extensions/trigger-compact.ts +50 -50
  480. package/examples/extensions/truncated-tool.ts +195 -195
  481. package/examples/extensions/widget-placement.ts +9 -9
  482. package/examples/extensions/with-deps/index.ts +32 -32
  483. package/examples/extensions/with-deps/package-lock.json +31 -31
  484. package/examples/extensions/with-deps/package.json +22 -22
  485. package/examples/extensions/working-indicator.ts +123 -123
  486. package/examples/extensions/working-message-test.ts +25 -25
  487. package/examples/rpc-extension-ui.ts +632 -632
  488. package/examples/sdk/01-minimal.ts +26 -26
  489. package/examples/sdk/02-custom-model.ts +53 -53
  490. package/examples/sdk/03-custom-prompt.ts +75 -75
  491. package/examples/sdk/04-skills.ts +55 -55
  492. package/examples/sdk/05-tools.ts +48 -48
  493. package/examples/sdk/06-extensions.ts +99 -99
  494. package/examples/sdk/07-context-files.ts +47 -47
  495. package/examples/sdk/08-prompt-templates.ts +51 -51
  496. package/examples/sdk/09-api-keys-and-oauth.ts +52 -52
  497. package/examples/sdk/10-settings.ts +53 -53
  498. package/examples/sdk/11-sessions.ts +52 -52
  499. package/examples/sdk/12-full-control.ts +79 -79
  500. package/examples/sdk/13-session-runtime.ts +67 -67
  501. package/examples/sdk/README.md +144 -144
  502. package/package.json +3 -3
@@ -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
+ });