@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,169 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { Box, type Component } from "@earendil-works/pi-tui";
4
+ import { renderEditDiffResult } from "../src/diff-renderer.ts";
5
+
6
+ const theme = {
7
+ fg: (_color: string, text: string): string => text,
8
+ bold: (text: string): string => text,
9
+ };
10
+
11
+ function stripAnsi(text: string): string {
12
+ return text.replace(/\x1b\[[0-9;]*m/g, "");
13
+ }
14
+
15
+ function renderInsideToolBox(component: Component, width: number): string[] {
16
+ const box = new Box(1, 1);
17
+ box.addChild(component);
18
+ return box.render(width).map(stripAnsi);
19
+ }
20
+
21
+ function extractDisplayedLineNumber(line: string): string | null {
22
+ const match = line.match(/^\s*(?:[▌+\-]?\s*)(\d*)\s+│/);
23
+ if (!match) {
24
+ return null;
25
+ }
26
+ return match[1] ?? "";
27
+ }
28
+
29
+ function countDisplayedLineNumber(lines: string[], lineNumber: string): number {
30
+ return lines.reduce((count, line) => count + (extractDisplayedLineNumber(line) === lineNumber ? 1 : 0), 0);
31
+ }
32
+
33
+ function extractUnifiedDiffRows(lines: string[]): string[] {
34
+ return lines.filter((line) => extractDisplayedLineNumber(line) !== null);
35
+ }
36
+
37
+ function splitRenderedRow(line: string, width: number): { left: string; right: string } {
38
+ const separatorWidth = 3;
39
+ const leftWidth = Math.floor((width - separatorWidth) / 2);
40
+ return {
41
+ left: line.slice(0, leftWidth),
42
+ right: line.slice(leftWidth + separatorWidth),
43
+ };
44
+ }
45
+
46
+ function extractSplitDiffRows(lines: string[], width: number): Array<{ left: string; right: string }> {
47
+ return lines
48
+ .map((line) => splitRenderedRow(line, width))
49
+ .filter(({ left, right }) => extractDisplayedLineNumber(left) !== null || extractDisplayedLineNumber(right) !== null);
50
+ }
51
+
52
+ function extractCellContent(cell: string): string {
53
+ const dividerIndex = cell.indexOf("│ ");
54
+ if (dividerIndex === -1) {
55
+ return "";
56
+ }
57
+ return cell.slice(dividerIndex + 2).trimEnd();
58
+ }
59
+
60
+ test("unified diff wrapped continuation rows should not repeat line numbers", () => {
61
+ const width = 60;
62
+ const component = renderEditDiffResult(
63
+ {
64
+ diff: "--- a/demo.txt\n+++ b/demo.txt\n@@ -1 +1 @@\n-this is a very long line that exceeds the available width and will wrap to multiple rows\n",
65
+ },
66
+ { expanded: false, filePath: "demo.txt" },
67
+ {
68
+ diffViewMode: "unified",
69
+ diffSplitMinWidth: 80,
70
+ diffCollapsedLines: 24,
71
+ diffWordWrap: true,
72
+ } as any,
73
+ theme,
74
+ "",
75
+ );
76
+
77
+ const lines = renderInsideToolBox(component, width);
78
+
79
+ assert.strictEqual(
80
+ countDisplayedLineNumber(lines, "1"),
81
+ 1,
82
+ `Expected wrapped unified rows to show line number 1 only once.\n${lines.join("\n")}`,
83
+ );
84
+ });
85
+
86
+ test("split diff falls back to unified with the same continuation numbering behavior", () => {
87
+ const width = 50;
88
+ const component = renderEditDiffResult(
89
+ {
90
+ diff: "--- a/demo.txt\n+++ b/demo.txt\n@@ -1 +1 @@\n-this is a very long line that will definitely need to wrap when rendered in narrow panes\n",
91
+ },
92
+ { expanded: false, filePath: "demo.txt" },
93
+ {
94
+ diffViewMode: "split",
95
+ diffSplitMinWidth: 80,
96
+ diffCollapsedLines: 24,
97
+ diffWordWrap: true,
98
+ } as any,
99
+ theme,
100
+ "",
101
+ );
102
+
103
+ const lines = renderInsideToolBox(component, width);
104
+
105
+ assert.strictEqual(
106
+ countDisplayedLineNumber(lines, "1"),
107
+ 1,
108
+ `Expected split fallback rows to show line number 1 only once.\n${lines.join("\n")}`,
109
+ );
110
+ });
111
+
112
+ test("multi-line unified diff keeps continuation rows blank while preserving logical line numbers", () => {
113
+ const width = 50;
114
+ const component = renderEditDiffResult(
115
+ {
116
+ diff: "--- a/demo.txt\n+++ b/demo.txt\n@@ -1,2 +1,2 @@\n-first very long line that will definitely need to wrap for sure\n-second very long line also wrapping because it is too long\n+first replacement also very long and needs to wrap\n+second replacement line that wraps too\n",
117
+ },
118
+ { expanded: false, filePath: "demo.txt" },
119
+ {
120
+ diffViewMode: "unified",
121
+ diffSplitMinWidth: 80,
122
+ diffCollapsedLines: 24,
123
+ diffWordWrap: true,
124
+ } as any,
125
+ theme,
126
+ "",
127
+ );
128
+
129
+ const lines = renderInsideToolBox(component, width);
130
+ const diffRows = extractUnifiedDiffRows(lines);
131
+ const displayedNumbers = diffRows.map(extractDisplayedLineNumber);
132
+
133
+ assert.ok(diffRows.length > 4, `Expected wrapped unified output to span multiple visual rows.\n${lines.join("\n")}`);
134
+ assert.strictEqual(countDisplayedLineNumber(diffRows, "1"), 2, `Expected logical line 1 once per side.\n${diffRows.join("\n")}`);
135
+ assert.strictEqual(countDisplayedLineNumber(diffRows, "2"), 2, `Expected logical line 2 once per side.\n${diffRows.join("\n")}`);
136
+ assert.ok(displayedNumbers.includes(""), `Expected at least one continuation row with a blank line number.\n${diffRows.join("\n")}`);
137
+ });
138
+
139
+ test("split diff keeps wrapped rows vertically aligned with blank placeholder cells", () => {
140
+ const width = 120;
141
+ const component = renderEditDiffResult(
142
+ {
143
+ diff: "--- a/demo.txt\n+++ b/demo.txt\n@@ -1 +1 @@\n-this is a very long original line that will wrap across multiple visual rows in split mode\n+short replacement\n",
144
+ },
145
+ { expanded: false, filePath: "demo.txt" },
146
+ {
147
+ diffViewMode: "split",
148
+ diffSplitMinWidth: 80,
149
+ diffCollapsedLines: 24,
150
+ diffWordWrap: true,
151
+ } as any,
152
+ theme,
153
+ "",
154
+ );
155
+
156
+ const lines = renderInsideToolBox(component, width);
157
+ const diffRows = extractSplitDiffRows(lines, width);
158
+ const firstRow = diffRows[0];
159
+ const secondRow = diffRows[1];
160
+
161
+ assert.ok(firstRow, `Expected at least one split diff row.\n${lines.join("\n")}`);
162
+ assert.ok(secondRow, `Expected a continuation row for the wrapped left side.\n${lines.join("\n")}`);
163
+ assert.strictEqual(extractDisplayedLineNumber(firstRow.left), "1", `Expected first left cell to show line number 1.\n${firstRow.left}`);
164
+ assert.strictEqual(extractDisplayedLineNumber(firstRow.right), "1", `Expected first right cell to show line number 1.\n${firstRow.right}`);
165
+ assert.strictEqual(extractDisplayedLineNumber(secondRow.left), "", `Expected wrapped left continuation row to blank its line number.\n${secondRow.left}`);
166
+ assert.strictEqual(extractCellContent(secondRow.left).length > 0, true, `Expected wrapped left continuation content to remain visible.\n${secondRow.left}`);
167
+ assert.strictEqual(extractDisplayedLineNumber(secondRow.right), "", `Expected blank placeholder row on the unwrapped right side.\n${secondRow.right}`);
168
+ assert.strictEqual(extractCellContent(secondRow.right), "", `Expected blank placeholder cell content on the unwrapped right side.\n${secondRow.right}`);
169
+ });
@@ -0,0 +1,354 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import type {
4
+ ExtensionAPI,
5
+ ExtensionCommandContext,
6
+ } from "@earendil-works/pi-coding-agent";
7
+ import toolDisplayExtension from "../src/index.ts";
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // Helpers
11
+ // ---------------------------------------------------------------------------
12
+
13
+ interface CapturedHandler {
14
+ event: string;
15
+ handler: (...args: unknown[]) => unknown;
16
+ }
17
+
18
+ interface CapturedCommand {
19
+ name: string;
20
+ description?: string;
21
+ handler?: (...args: unknown[]) => unknown;
22
+ }
23
+
24
+ function createApiStub(
25
+ overrides: Partial<{
26
+ registerTool: (tool: unknown) => void;
27
+ registerCommand: (name: string, cmd: unknown) => void;
28
+ on: (event: string, handler: (...args: unknown[]) => unknown) => void;
29
+ getAllTools: () => unknown[];
30
+ getCommands: () => Array<{ name: string }>;
31
+ }> = {},
32
+ ): {
33
+ api: ExtensionAPI;
34
+ capturedTools: Array<{ name: string } & Record<string, unknown>>;
35
+ capturedCommands: CapturedCommand[];
36
+ capturedHandlers: CapturedHandler[];
37
+ } {
38
+ const capturedTools: Array<{ name: string } & Record<string, unknown>> = [];
39
+ const capturedCommands: CapturedCommand[] = [];
40
+ const capturedHandlers: CapturedHandler[] = [];
41
+
42
+ const api = {
43
+ registerTool(tool: unknown): void {
44
+ capturedTools.push(tool as { name: string } & Record<string, unknown>);
45
+ overrides.registerTool?.(tool);
46
+ },
47
+ registerCommand(name: string, cmd: unknown): void {
48
+ capturedCommands.push({ name, ...(cmd as object) } as CapturedCommand);
49
+ overrides.registerCommand?.(name, cmd);
50
+ },
51
+ on(event: string, handler: (...args: unknown[]) => unknown): void {
52
+ capturedHandlers.push({ event, handler });
53
+ overrides.on?.(event, handler);
54
+ },
55
+ getAllTools(): unknown[] {
56
+ return overrides.getAllTools?.() ?? [];
57
+ },
58
+ getCommands(): Array<{ name: string }> {
59
+ return overrides.getCommands?.() ?? [];
60
+ },
61
+ } as unknown as ExtensionAPI;
62
+
63
+ return { api, capturedTools, capturedCommands, capturedHandlers };
64
+ }
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Tests
68
+ // ---------------------------------------------------------------------------
69
+
70
+ test("entry point registers expected lifecycle handlers", () => {
71
+ const { api, capturedHandlers } = createApiStub();
72
+ toolDisplayExtension(api);
73
+
74
+ const eventNames = capturedHandlers.map((h) => h.event);
75
+ // Thinking-label handlers
76
+ assert.ok(eventNames.includes("message_update"), "message_update handler registered");
77
+ assert.ok(eventNames.includes("message_end"), "message_end handler registered");
78
+ assert.ok(eventNames.includes("context"), "context handler registered");
79
+ // Lifecycle handlers from index.ts directly
80
+ assert.ok(eventNames.includes("session_start"), "session_start handler registered");
81
+ assert.ok(eventNames.includes("before_agent_start"), "before_agent_start handler registered");
82
+ // User-message-box lifecycle handlers
83
+ const sessionStartCount = eventNames.filter((e) => e === "session_start").length;
84
+ assert.ok(sessionStartCount >= 1, "at least one session_start handler registered");
85
+ const beforeAgentStartCount = eventNames.filter((e) => e === "before_agent_start").length;
86
+ assert.ok(beforeAgentStartCount >= 1, "at least one before_agent_start handler registered");
87
+ });
88
+
89
+ test("entry point registers tool-display command", () => {
90
+ const { api, capturedCommands } = createApiStub();
91
+ toolDisplayExtension(api);
92
+
93
+ const cmdNames = capturedCommands.map((c) => c.name);
94
+ assert.ok(cmdNames.includes("tool-display"), "tool-display command registered");
95
+ });
96
+
97
+ test("entry point registers built-in tool overrides", () => {
98
+ const { api, capturedTools } = createApiStub();
99
+ toolDisplayExtension(api);
100
+
101
+ const toolNames = capturedTools.map((t) => t.name);
102
+ // find, ls, write are registered immediately; read/grep/edit/bash are deferred
103
+ assert.ok(toolNames.includes("find"), "find tool override registered");
104
+ assert.ok(toolNames.includes("ls"), "ls tool override registered");
105
+ assert.ok(toolNames.includes("write"), "write tool override registered");
106
+
107
+ // Disabled tools (if config disables them) would not appear; the default
108
+ // config enables all, so we expect at least these 3 immediately.
109
+ assert.ok(toolNames.length >= 3, "at least 3 tool overrides registered immediately");
110
+ });
111
+
112
+ test("session_start handler refreshes capabilities and notifies pending errors", async () => {
113
+ const { api, capturedHandlers } = createApiStub();
114
+ toolDisplayExtension(api);
115
+
116
+ const sessionHandler = capturedHandlers.find((h) => h.event === "session_start")?.handler;
117
+ assert.ok(sessionHandler, "session_start handler captured");
118
+
119
+ const ctx = {
120
+ ui: {
121
+ theme: { fg: (_c: string, t: string) => t },
122
+ notify: (_msg: string, _level: string) => { /* no-op */ },
123
+ },
124
+ };
125
+
126
+ // Should not throw
127
+ await assert.doesNotReject(async () => sessionHandler({}, ctx));
128
+ });
129
+
130
+ test("before_agent_start handler refreshes capabilities without crashing", async () => {
131
+ const { api, capturedHandlers } = createApiStub();
132
+ toolDisplayExtension(api);
133
+
134
+ const beforeHandler = capturedHandlers.find((h) => h.event === "before_agent_start")?.handler;
135
+ assert.ok(beforeHandler, "before_agent_start handler captured");
136
+
137
+ // Should not throw
138
+ await assert.doesNotReject(async () => beforeHandler());
139
+ });
140
+
141
+ test("multiple calls to toolDisplayExtension are idempotent", () => {
142
+ const { api, capturedTools, capturedCommands, capturedHandlers } = createApiStub();
143
+
144
+ // Call twice
145
+ toolDisplayExtension(api);
146
+ toolDisplayExtension(api);
147
+
148
+ // Second call should not throw. Tools may be registered again (that's up
149
+ // to the extension loader to deduplicate), but the extension itself must
150
+ // not crash.
151
+ const toolNames = capturedTools.map((t) => t.name);
152
+ assert.ok(toolNames.filter((n) => n === "find").length >= 1, "find registered at least once");
153
+ assert.ok(toolNames.filter((n) => n === "ls").length >= 1, "ls registered at least once");
154
+ assert.ok(toolNames.filter((n) => n === "write").length >= 1, "write registered at least once");
155
+
156
+ const cmdNames = capturedCommands.map((c) => c.name);
157
+ assert.ok(cmdNames.filter((n) => n === "tool-display").length >= 1, "command registered at least once");
158
+ });
159
+
160
+ test("entry point tolerates empty getAllTools and getCommands results", () => {
161
+ // Stub that returns empty arrays for discovery methods
162
+ const { api } = createApiStub({
163
+ getAllTools: () => [],
164
+ getCommands: () => [],
165
+ });
166
+
167
+ assert.doesNotThrow(() => toolDisplayExtension(api));
168
+ });
169
+
170
+ test("entry point tolerates tools with existing owners in getAllTools", () => {
171
+ const { api } = createApiStub({
172
+ getAllTools: () => [
173
+ { name: "read", sourceInfo: { source: "local", path: "/ext/read.ts" } },
174
+ { name: "edit", sourceInfo: { source: "local", path: "/ext/edit.ts" } },
175
+ { name: "grep", sourceInfo: { source: "local", path: "/ext/grep.ts" } },
176
+ ],
177
+ getCommands: () => [{ name: "custom" }],
178
+ });
179
+
180
+ assert.doesNotThrow(() => toolDisplayExtension(api));
181
+ });
182
+
183
+ test("graceful degradation: extension throws when registerCommand is missing", () => {
184
+ // Simulate a minimal stub missing registerCommand
185
+ const minimalApi = {
186
+ registerTool(): void { /* no-op */ },
187
+ on(): void { /* no-op */ },
188
+ getAllTools(): unknown[] { return []; },
189
+ getCommands(): Array<{ name: string }> { return []; },
190
+ } as unknown as ExtensionAPI;
191
+
192
+ // registerToolDisplayCommand calls pi.registerCommand directly, so this
193
+ // is expected to throw in a peer-dep mismatch scenario.
194
+ assert.throws(
195
+ () => toolDisplayExtension(minimalApi),
196
+ /registerCommand/i,
197
+ "missing registerCommand should propagate",
198
+ );
199
+ });
200
+
201
+ test("graceful degradation: extension throws when on is missing", () => {
202
+ const minimalApi = {
203
+ registerTool(): void { /* no-op */ },
204
+ registerCommand(): void { /* no-op */ },
205
+ getAllTools(): unknown[] { return []; },
206
+ getCommands(): Array<{ name: string }> { return []; },
207
+ } as unknown as ExtensionAPI;
208
+
209
+ // registerNativeUserMessageBox calls pi.on, so this should throw when on is missing
210
+ assert.throws(
211
+ () => toolDisplayExtension(minimalApi),
212
+ /pi\.on is not a function|on is not a function/i,
213
+ "missing on should propagate",
214
+ );
215
+ });
216
+
217
+ test("lifecycle events fire in expected order during a session lifecycle", async () => {
218
+ // Simulate the sequence: setup → before_agent_start → session_start
219
+ const { api, capturedHandlers } = createApiStub();
220
+
221
+ toolDisplayExtension(api);
222
+
223
+ // Manually invoke handlers in expected lifecycle order
224
+ const beforeHandler = capturedHandlers.find((h) => h.event === "before_agent_start")?.handler;
225
+ const sessionHandler = capturedHandlers.find((h) => h.event === "session_start")?.handler;
226
+ const messageUpdateHandler = capturedHandlers.find((h) => h.event === "message_update")?.handler;
227
+ const messageEndHandler = capturedHandlers.find((h) => h.event === "message_end")?.handler;
228
+ const contextHandler = capturedHandlers.find((h) => h.event === "context")?.handler;
229
+
230
+ assert.ok(beforeHandler, "before_agent_start handler found");
231
+ assert.ok(sessionHandler, "session_start handler found");
232
+
233
+ // Simulate a session lifecycle
234
+ await beforeHandler();
235
+ await sessionHandler(
236
+ {},
237
+ { ui: { theme: { fg: (_c: string, t: string) => t }, notify: () => {} } },
238
+ );
239
+
240
+ // Simulate message lifecycle for thinking labels
241
+ if (messageUpdateHandler) {
242
+ await messageUpdateHandler(
243
+ {
244
+ message: {
245
+ role: "assistant",
246
+ api: "anthropic-messages",
247
+ content: [{ type: "thinking", thinking: "test" }],
248
+ },
249
+ },
250
+ { ui: { theme: { fg: (_c: string, t: string) => `[${_c}]${t}` } } },
251
+ );
252
+ }
253
+
254
+ if (messageEndHandler) {
255
+ await messageEndHandler(
256
+ {
257
+ message: {
258
+ role: "assistant",
259
+ api: "openai-chat",
260
+ content: [{ type: "thinking", thinking: "done" }],
261
+ },
262
+ },
263
+ {},
264
+ );
265
+ }
266
+
267
+ if (contextHandler) {
268
+ await contextHandler(
269
+ {
270
+ messages: [
271
+ {
272
+ role: "assistant",
273
+ content: [{ type: "thinking", thinking: "\x1b[31mThinking: \x1b[0mcontext" }],
274
+ },
275
+ ],
276
+ },
277
+ {},
278
+ );
279
+ }
280
+
281
+ // All handlers executed without throwing - this is the main assertion
282
+ assert.ok(true, "lifecycle handlers completed without error");
283
+ });
284
+
285
+ test("session_start handler tolerates missing ctx.ui", async () => {
286
+ const { api, capturedHandlers } = createApiStub();
287
+ toolDisplayExtension(api);
288
+
289
+ const sessionHandler = capturedHandlers.find((h) => h.event === "session_start")?.handler;
290
+ assert.ok(sessionHandler);
291
+
292
+ // ctx with no ui (edge case from older pi versions)
293
+ await assert.doesNotReject(async () => sessionHandler({}, {}));
294
+ });
295
+
296
+ test("before_agent_start handler tolerates being called multiple times", async () => {
297
+ const { api, capturedHandlers } = createApiStub();
298
+ toolDisplayExtension(api);
299
+
300
+ const beforeHandler = capturedHandlers.find((h) => h.event === "before_agent_start")?.handler;
301
+ assert.ok(beforeHandler);
302
+
303
+ await assert.doesNotReject(async () => beforeHandler());
304
+ await assert.doesNotReject(async () => beforeHandler());
305
+ await assert.doesNotReject(async () => beforeHandler());
306
+ });
307
+
308
+ test("session_start handler tolerates being called multiple times", async () => {
309
+ const { api, capturedHandlers } = createApiStub();
310
+ toolDisplayExtension(api);
311
+
312
+ const sessionHandler = capturedHandlers.find((h) => h.event === "session_start")?.handler;
313
+ assert.ok(sessionHandler);
314
+
315
+ const ctx = { ui: { theme: {}, notify: () => {} } };
316
+ await assert.doesNotReject(async () => sessionHandler({}, ctx));
317
+ await assert.doesNotReject(async () => sessionHandler({}, ctx));
318
+ await assert.doesNotReject(async () => sessionHandler({}, ctx));
319
+ });
320
+
321
+ test("overridden tools include renderCall and renderResult functions", () => {
322
+ const { api, capturedTools } = createApiStub();
323
+ toolDisplayExtension(api);
324
+
325
+ for (const tool of capturedTools) {
326
+ assert.ok(
327
+ typeof tool.renderCall === "function",
328
+ `${tool.name} has renderCall`,
329
+ );
330
+ assert.ok(
331
+ typeof tool.renderResult === "function",
332
+ `${tool.name} has renderResult`,
333
+ );
334
+ }
335
+ });
336
+
337
+ test("overridden tools preserve promptSnippet and promptGuidelines from built-ins", () => {
338
+ const { api, capturedTools } = createApiStub();
339
+ toolDisplayExtension(api);
340
+
341
+ const byName = new Map(capturedTools.map((t) => [t.name, t]));
342
+
343
+ // read (deferred) won't be registered immediately; it's deferred
344
+ // So we only check tools registered immediately
345
+ for (const name of ["find", "ls", "write"] as const) {
346
+ const tool = byName.get(name);
347
+ assert.ok(tool, `${name} is registered`);
348
+ // promptSnippet should be a non-empty string or undefined
349
+ // (built-in tools may or may not have promptSnippet)
350
+ if (tool.promptSnippet !== undefined) {
351
+ assert.equal(typeof tool.promptSnippet, "string");
352
+ }
353
+ }
354
+ });
@@ -0,0 +1,79 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import test from "node:test";
6
+ import {
7
+ buildPendingEditPreviewData,
8
+ buildPendingWritePreviewData,
9
+ } from "../src/pending-diff-preview.ts";
10
+
11
+ function withTempWorkspace(name: string, run: (workspace: string) => void): void {
12
+ const workspace = mkdtempSync(join(tmpdir(), name));
13
+ try {
14
+ run(workspace);
15
+ } finally {
16
+ rmSync(workspace, { recursive: true, force: true });
17
+ }
18
+ }
19
+
20
+ test("pending write preview compares existing safe workspace files", () => {
21
+ withTempWorkspace("pi-tool-display-write-preview-", (workspace) => {
22
+ writeFileSync(join(workspace, "sample.txt"), "before\n", "utf8");
23
+
24
+ const preview = buildPendingWritePreviewData(
25
+ { path: "sample.txt", content: "after\n" },
26
+ workspace,
27
+ );
28
+
29
+ assert.equal(preview?.fileExistedBeforeWrite, true);
30
+ assert.equal(preview?.previousContent, "before\n");
31
+ assert.equal(preview?.nextContent, "after\n");
32
+ assert.equal(preview?.notice, undefined);
33
+ });
34
+ });
35
+
36
+ test("pending preview skips direct reads outside the workspace", () => {
37
+ withTempWorkspace("pi-tool-display-boundary-", (workspace) => {
38
+ const outside = mkdtempSync(join(tmpdir(), "pi-tool-display-outside-"));
39
+ try {
40
+ const outsideFile = join(outside, "secret.txt");
41
+ writeFileSync(outsideFile, "secret\n", "utf8");
42
+
43
+ const editPreview = buildPendingEditPreviewData(
44
+ { path: outsideFile, oldText: "secret", newText: "safe" },
45
+ workspace,
46
+ );
47
+ const writePreview = buildPendingWritePreviewData(
48
+ { path: outsideFile, content: "replacement\n" },
49
+ workspace,
50
+ );
51
+
52
+ assert.equal(editPreview?.previousContent, undefined);
53
+ assert.equal(editPreview?.nextContent, undefined);
54
+ assert.match(editPreview?.notice ?? "", /outside the current workspace/);
55
+ assert.equal(writePreview?.previousContent, undefined);
56
+ assert.equal(writePreview?.nextContent, "replacement\n");
57
+ assert.match(writePreview?.notice ?? "", /outside the current workspace/);
58
+ } finally {
59
+ rmSync(outside, { recursive: true, force: true });
60
+ }
61
+ });
62
+ });
63
+
64
+ test("pending preview skips files over the read-size limit", () => {
65
+ withTempWorkspace("pi-tool-display-large-preview-", (workspace) => {
66
+ mkdirSync(join(workspace, "nested"));
67
+ const nestedFile = join(workspace, "nested", "large.txt");
68
+ writeFileSync(nestedFile, "x".repeat(1_000_001), "utf8");
69
+
70
+ const preview = buildPendingEditPreviewData(
71
+ { path: "nested/large.txt", oldText: "x", newText: "y" },
72
+ workspace,
73
+ );
74
+
75
+ assert.equal(preview?.previousContent, undefined);
76
+ assert.equal(preview?.nextContent, undefined);
77
+ assert.match(preview?.notice ?? "", /preview read limit/);
78
+ });
79
+ });