@code-yeongyu/senpi 2026.6.10 → 2026.6.13

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 (285) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/README.md +21 -21
  3. package/dist/cli/startup-ui.d.ts +10 -0
  4. package/dist/cli/startup-ui.d.ts.map +1 -1
  5. package/dist/cli/startup-ui.js +72 -1
  6. package/dist/cli/startup-ui.js.map +1 -1
  7. package/dist/core/agent-session.d.ts.map +1 -1
  8. package/dist/core/agent-session.js +3 -2
  9. package/dist/core/agent-session.js.map +1 -1
  10. package/dist/core/bash-executor.d.ts.map +1 -1
  11. package/dist/core/bash-executor.js +31 -7
  12. package/dist/core/bash-executor.js.map +1 -1
  13. package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts +0 -1
  14. package/dist/core/extensions/builtin/compaction/degradation-monitor.d.ts.map +1 -1
  15. package/dist/core/extensions/builtin/compaction/degradation-monitor.js +0 -1
  16. package/dist/core/extensions/builtin/compaction/degradation-monitor.js.map +1 -1
  17. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  18. package/dist/core/extensions/builtin/compaction/index.js +4 -4
  19. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  20. package/dist/core/extensions/builtin/compaction/policy.d.ts +0 -5
  21. package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
  22. package/dist/core/extensions/builtin/compaction/policy.js +0 -4
  23. package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
  24. package/dist/core/extensions/builtin/compaction/speculative.d.ts +0 -6
  25. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  26. package/dist/core/extensions/builtin/compaction/speculative.js +0 -3
  27. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  28. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts +1 -1
  29. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +10 -2
  31. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
  32. package/dist/core/extensions/builtin/permission-system/cli.d.ts +0 -3
  33. package/dist/core/extensions/builtin/permission-system/cli.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/permission-system/cli.js +0 -13
  35. package/dist/core/extensions/builtin/permission-system/cli.js.map +1 -1
  36. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts +3 -0
  37. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -0
  38. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +10 -0
  39. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -0
  40. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  41. package/dist/core/extensions/builtin/prompt-preset/presets.js +12 -0
  42. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  43. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  44. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  46. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  47. package/dist/core/extensions/types.d.ts +1 -0
  48. package/dist/core/extensions/types.d.ts.map +1 -1
  49. package/dist/core/extensions/types.js.map +1 -1
  50. package/dist/core/model-registry.d.ts +0 -3
  51. package/dist/core/model-registry.d.ts.map +1 -1
  52. package/dist/core/model-registry.js +3 -3
  53. package/dist/core/model-registry.js.map +1 -1
  54. package/dist/core/model-resolver.d.ts +1 -0
  55. package/dist/core/model-resolver.d.ts.map +1 -1
  56. package/dist/core/model-resolver.js +43 -6
  57. package/dist/core/model-resolver.js.map +1 -1
  58. package/dist/core/project-trust.js +2 -2
  59. package/dist/core/project-trust.js.map +1 -1
  60. package/dist/core/resolve-config-value.d.ts +0 -4
  61. package/dist/core/resolve-config-value.d.ts.map +1 -1
  62. package/dist/core/resolve-config-value.js +0 -15
  63. package/dist/core/resolve-config-value.js.map +1 -1
  64. package/dist/core/session-manager.d.ts.map +1 -1
  65. package/dist/core/session-manager.js +11 -2
  66. package/dist/core/session-manager.js.map +1 -1
  67. package/dist/core/settings-manager.d.ts +6 -0
  68. package/dist/core/settings-manager.d.ts.map +1 -1
  69. package/dist/core/settings-manager.js +17 -0
  70. package/dist/core/settings-manager.js.map +1 -1
  71. package/dist/core/tools/edit-diff.d.ts +0 -5
  72. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  73. package/dist/core/tools/edit-diff.js +0 -7
  74. package/dist/core/tools/edit-diff.js.map +1 -1
  75. package/dist/core/tools/index.d.ts +0 -5
  76. package/dist/core/tools/index.d.ts.map +1 -1
  77. package/dist/core/tools/index.js +0 -67
  78. package/dist/core/tools/index.js.map +1 -1
  79. package/dist/core/tools/output-accumulator.d.ts +3 -5
  80. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  81. package/dist/core/tools/output-accumulator.js +38 -34
  82. package/dist/core/tools/output-accumulator.js.map +1 -1
  83. package/dist/core/tools/tail-window.d.ts +15 -0
  84. package/dist/core/tools/tail-window.d.ts.map +1 -0
  85. package/dist/core/tools/tail-window.js +75 -0
  86. package/dist/core/tools/tail-window.js.map +1 -0
  87. package/dist/core/trust-manager.d.ts +8 -3
  88. package/dist/core/trust-manager.d.ts.map +1 -1
  89. package/dist/core/trust-manager.js +26 -11
  90. package/dist/core/trust-manager.js.map +1 -1
  91. package/dist/index.d.ts +1 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/main.d.ts.map +1 -1
  96. package/dist/main.js +17 -6
  97. package/dist/main.js.map +1 -1
  98. package/dist/modes/interactive/aborted-error-label.d.ts +2 -0
  99. package/dist/modes/interactive/aborted-error-label.d.ts.map +1 -0
  100. package/dist/modes/interactive/aborted-error-label.js +8 -0
  101. package/dist/modes/interactive/aborted-error-label.js.map +1 -0
  102. package/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  103. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
  104. package/dist/modes/interactive/components/first-time-setup.js +101 -0
  105. package/dist/modes/interactive/components/first-time-setup.js.map +1 -0
  106. package/dist/modes/interactive/components/index.d.ts +1 -0
  107. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  108. package/dist/modes/interactive/components/index.js +1 -0
  109. package/dist/modes/interactive/components/index.js.map +1 -1
  110. package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  111. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  112. package/dist/modes/interactive/components/tool-execution.js +45 -0
  113. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  114. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  115. package/dist/modes/interactive/components/trust-selector.js +4 -4
  116. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  117. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  118. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  119. package/dist/modes/interactive/interactive-mode.js +18 -18
  120. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  121. package/dist/modes/interactive/theme/theme.d.ts +0 -4
  122. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  123. package/dist/modes/interactive/theme/theme.js +0 -7
  124. package/dist/modes/interactive/theme/theme.js.map +1 -1
  125. package/dist/modes/print-mode.d.ts.map +1 -1
  126. package/dist/modes/print-mode.js +1 -1
  127. package/dist/modes/print-mode.js.map +1 -1
  128. package/dist/modes/rpc/event-output-buffer.d.ts +10 -0
  129. package/dist/modes/rpc/event-output-buffer.d.ts.map +1 -0
  130. package/dist/modes/rpc/event-output-buffer.js +27 -0
  131. package/dist/modes/rpc/event-output-buffer.js.map +1 -0
  132. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  133. package/dist/modes/rpc/jsonl.js +9 -11
  134. package/dist/modes/rpc/jsonl.js.map +1 -1
  135. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  136. package/dist/modes/rpc/rpc-mode.js +17 -7
  137. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  138. package/dist/modes/rpc/rpc-types.d.ts +0 -1
  139. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  140. package/dist/modes/rpc/rpc-types.js.map +1 -1
  141. package/dist/package-manager-cli.d.ts.map +1 -1
  142. package/dist/package-manager-cli.js +10 -3
  143. package/dist/package-manager-cli.js.map +1 -1
  144. package/dist/utils/shell.d.ts.map +1 -1
  145. package/dist/utils/shell.js +14 -0
  146. package/dist/utils/shell.js.map +1 -1
  147. package/docs/compaction-guide.md +9 -9
  148. package/docs/compaction.md +2 -2
  149. package/docs/containerization.md +22 -22
  150. package/docs/custom-provider.md +13 -13
  151. package/docs/development.md +4 -2
  152. package/docs/extensions.md +18 -19
  153. package/docs/index.md +4 -4
  154. package/docs/json.md +21 -15
  155. package/docs/keybindings.md +6 -3
  156. package/docs/models.md +6 -6
  157. package/docs/packages.md +11 -11
  158. package/docs/prompt-templates.md +2 -2
  159. package/docs/providers.md +9 -9
  160. package/docs/rpc.md +14 -13
  161. package/docs/sdk.md +13 -9
  162. package/docs/security.md +14 -10
  163. package/docs/session-format.md +4 -4
  164. package/docs/sessions.md +14 -14
  165. package/docs/settings.md +14 -12
  166. package/docs/skills.md +8 -8
  167. package/docs/terminal-setup.md +2 -2
  168. package/docs/termux.md +3 -3
  169. package/docs/tui.md +4 -4
  170. package/docs/usage.md +52 -59
  171. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  172. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  173. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  174. package/examples/extensions/gondolin/package-lock.json +2 -2
  175. package/examples/extensions/gondolin/package.json +1 -1
  176. package/examples/extensions/sandbox/package-lock.json +2 -2
  177. package/examples/extensions/sandbox/package.json +1 -1
  178. package/examples/extensions/with-deps/package-lock.json +2 -2
  179. package/examples/extensions/with-deps/package.json +1 -1
  180. package/node_modules/@earendil-works/pi-agent-core/README.md +4 -3
  181. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
  182. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +0 -2
  184. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
  185. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js +0 -4
  186. package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
  187. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +7 -2
  188. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  189. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  190. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  191. package/node_modules/@earendil-works/pi-ai/README.md +2 -4
  192. package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts +0 -1
  193. package/node_modules/@earendil-works/pi-ai/dist/api-registry.d.ts.map +1 -1
  194. package/node_modules/@earendil-works/pi-ai/dist/api-registry.js +0 -3
  195. package/node_modules/@earendil-works/pi-ai/dist/api-registry.js.map +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  197. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +252 -470
  198. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +533 -740
  200. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  201. package/node_modules/@earendil-works/pi-ai/dist/models.js +12 -5
  202. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +11 -2
  205. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  206. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  207. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +29 -16
  208. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  209. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts +0 -4
  210. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js +0 -13
  212. package/node_modules/@earendil-works/pi-ai/dist/providers/google-shared.js.map +1 -1
  213. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  214. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +3 -1
  215. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  216. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts +0 -6
  217. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +0 -14
  219. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
  221. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  223. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts +4 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js +59 -19
  226. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -5
  228. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -8
  230. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  231. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  232. package/node_modules/@earendil-works/pi-tui/README.md +1 -2
  233. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +2 -0
  234. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  235. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +93 -9
  236. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  237. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +3 -1
  238. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
  239. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +89 -2
  240. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
  241. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +1 -1
  242. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
  243. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -2
  245. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  246. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -2
  247. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  248. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +1 -0
  249. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  250. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +15 -8
  251. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -1
  253. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +1 -1
  254. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +4 -7
  255. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +1 -1
  256. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  257. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +0 -1
  258. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  259. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +2 -1
  260. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  261. package/node_modules/@earendil-works/pi-tui/dist/tui.js +72 -16
  262. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  263. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -4
  264. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
  265. package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -7
  266. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  267. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  268. package/npm-shrinkwrap.json +12 -12
  269. package/package.json +5 -5
  270. package/dist/core/experimental.d.ts +0 -2
  271. package/dist/core/experimental.d.ts.map +0 -1
  272. package/dist/core/experimental.js +0 -4
  273. package/dist/core/experimental.js.map +0 -1
  274. package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts +0 -11
  275. package/dist/core/extensions/builtin/compaction/overflow-detection.d.ts.map +0 -1
  276. package/dist/core/extensions/builtin/compaction/overflow-detection.js +0 -40
  277. package/dist/core/extensions/builtin/compaction/overflow-detection.js.map +0 -1
  278. package/dist/core/extensions/builtin/system-messages.d.ts +0 -47
  279. package/dist/core/extensions/builtin/system-messages.d.ts.map +0 -1
  280. package/dist/core/extensions/builtin/system-messages.js +0 -117
  281. package/dist/core/extensions/builtin/system-messages.js.map +0 -1
  282. package/dist/core/index.d.ts +0 -13
  283. package/dist/core/index.d.ts.map +0 -1
  284. package/dist/core/index.js +0 -13
  285. package/dist/core/index.js.map +0 -1
@@ -15,62 +15,6 @@ import { createLsTool, createLsToolDefinition } from "./ls.js";
15
15
  import { createReadTool, createReadToolDefinition } from "./read.js";
16
16
  import { createWriteTool, createWriteToolDefinition } from "./write.js";
17
17
  export const allToolNames = new Set(["read", "bash", "edit", "write", "grep", "find", "ls"]);
18
- export function createToolDefinition(toolName, cwd, options) {
19
- switch (toolName) {
20
- case "read":
21
- return createReadToolDefinition(cwd, options?.read);
22
- case "bash":
23
- return createBashToolDefinition(cwd, options?.bash);
24
- case "edit":
25
- return createEditToolDefinition(cwd, options?.edit);
26
- case "write":
27
- return createWriteToolDefinition(cwd, options?.write);
28
- case "grep":
29
- return createGrepToolDefinition(cwd, options?.grep);
30
- case "find":
31
- return createFindToolDefinition(cwd, options?.find);
32
- case "ls":
33
- return createLsToolDefinition(cwd, options?.ls);
34
- default:
35
- throw new Error(`Unknown tool name: ${toolName}`);
36
- }
37
- }
38
- export function createTool(toolName, cwd, options) {
39
- switch (toolName) {
40
- case "read":
41
- return createReadTool(cwd, options?.read);
42
- case "bash":
43
- return createBashTool(cwd, options?.bash);
44
- case "edit":
45
- return createEditTool(cwd, options?.edit);
46
- case "write":
47
- return createWriteTool(cwd, options?.write);
48
- case "grep":
49
- return createGrepTool(cwd, options?.grep);
50
- case "find":
51
- return createFindTool(cwd, options?.find);
52
- case "ls":
53
- return createLsTool(cwd, options?.ls);
54
- default:
55
- throw new Error(`Unknown tool name: ${toolName}`);
56
- }
57
- }
58
- export function createCodingToolDefinitions(cwd, options) {
59
- return [
60
- createReadToolDefinition(cwd, options?.read),
61
- createBashToolDefinition(cwd, options?.bash),
62
- createEditToolDefinition(cwd, options?.edit),
63
- createWriteToolDefinition(cwd, options?.write),
64
- ];
65
- }
66
- export function createReadOnlyToolDefinitions(cwd, options) {
67
- return [
68
- createReadToolDefinition(cwd, options?.read),
69
- createGrepToolDefinition(cwd, options?.grep),
70
- createFindToolDefinition(cwd, options?.find),
71
- createLsToolDefinition(cwd, options?.ls),
72
- ];
73
- }
74
18
  export function createAllToolDefinitions(cwd, options) {
75
19
  return {
76
20
  read: createReadToolDefinition(cwd, options?.read),
@@ -98,15 +42,4 @@ export function createReadOnlyTools(cwd, options) {
98
42
  createLsTool(cwd, options?.ls),
99
43
  ];
100
44
  }
101
- export function createAllTools(cwd, options) {
102
- return {
103
- read: createReadTool(cwd, options?.read),
104
- bash: createBashTool(cwd, options?.bash),
105
- edit: createEditTool(cwd, options?.edit),
106
- write: createWriteTool(cwd, options?.write),
107
- grep: createGrepTool(cwd, options?.grep),
108
- find: createFindTool(cwd, options?.find),
109
- ls: createLsTool(cwd, options?.ls),
110
- };
111
- }
112
45
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.ts\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.ts\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.ts\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.ts\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.ts\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.ts\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.ts\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.ts\";\n\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.ts\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.ts\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.ts\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.ts\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.ts\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.ts\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.ts\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createToolDefinition(toolName: ToolName, cwd: string, options?: ToolsOptions): ToolDef {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadToolDefinition(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashToolDefinition(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditToolDefinition(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteToolDefinition(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepToolDefinition(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindToolDefinition(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsToolDefinition(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createTool(toolName: ToolName, cwd: string, options?: ToolsOptions): Tool {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn createReadTool(cwd, options?.read);\n\t\tcase \"bash\":\n\t\t\treturn createBashTool(cwd, options?.bash);\n\t\tcase \"edit\":\n\t\t\treturn createEditTool(cwd, options?.edit);\n\t\tcase \"write\":\n\t\t\treturn createWriteTool(cwd, options?.write);\n\t\tcase \"grep\":\n\t\t\treturn createGrepTool(cwd, options?.grep);\n\t\tcase \"find\":\n\t\t\treturn createFindTool(cwd, options?.find);\n\t\tcase \"ls\":\n\t\t\treturn createLsTool(cwd, options?.ls);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown tool name: ${toolName}`);\n\t}\n}\n\nexport function createCodingToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateBashToolDefinition(cwd, options?.bash),\n\t\tcreateEditToolDefinition(cwd, options?.edit),\n\t\tcreateWriteToolDefinition(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyToolDefinitions(cwd: string, options?: ToolsOptions): ToolDef[] {\n\treturn [\n\t\tcreateReadToolDefinition(cwd, options?.read),\n\t\tcreateGrepToolDefinition(cwd, options?.grep),\n\t\tcreateFindToolDefinition(cwd, options?.find),\n\t\tcreateLsToolDefinition(cwd, options?.ls),\n\t];\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n\nexport function createAllTools(cwd: string, options?: ToolsOptions): Record<ToolName, Tool> {\n\treturn {\n\t\tread: createReadTool(cwd, options?.read),\n\t\tbash: createBashTool(cwd, options?.bash),\n\t\tedit: createEditTool(cwd, options?.edit),\n\t\twrite: createWriteTool(cwd, options?.write),\n\t\tgrep: createGrepTool(cwd, options?.grep),\n\t\tfind: createFindTool(cwd, options?.find),\n\t\tls: createLsTool(cwd, options?.ls),\n\t};\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/tools/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n\ttype BashOperations,\n\ttype BashSpawnContext,\n\ttype BashSpawnHook,\n\ttype BashToolDetails,\n\ttype BashToolInput,\n\ttype BashToolOptions,\n\tcreateBashTool,\n\tcreateBashToolDefinition,\n\tcreateLocalBashOperations,\n} from \"./bash.ts\";\nexport {\n\tcreateEditTool,\n\tcreateEditToolDefinition,\n\ttype EditOperations,\n\ttype EditToolDetails,\n\ttype EditToolInput,\n\ttype EditToolOptions,\n} from \"./edit.ts\";\nexport { withFileMutationQueue } from \"./file-mutation-queue.ts\";\nexport {\n\tcreateFindTool,\n\tcreateFindToolDefinition,\n\ttype FindOperations,\n\ttype FindToolDetails,\n\ttype FindToolInput,\n\ttype FindToolOptions,\n} from \"./find.ts\";\nexport {\n\tcreateGrepTool,\n\tcreateGrepToolDefinition,\n\ttype GrepOperations,\n\ttype GrepToolDetails,\n\ttype GrepToolInput,\n\ttype GrepToolOptions,\n} from \"./grep.ts\";\nexport {\n\tcreateLsTool,\n\tcreateLsToolDefinition,\n\ttype LsOperations,\n\ttype LsToolDetails,\n\ttype LsToolInput,\n\ttype LsToolOptions,\n} from \"./ls.ts\";\nexport {\n\tcreateReadTool,\n\tcreateReadToolDefinition,\n\ttype ReadOperations,\n\ttype ReadToolDetails,\n\ttype ReadToolInput,\n\ttype ReadToolOptions,\n} from \"./read.ts\";\nexport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationOptions,\n\ttype TruncationResult,\n\ttruncateHead,\n\ttruncateLine,\n\ttruncateTail,\n} from \"./truncate.ts\";\nexport {\n\tcreateWriteTool,\n\tcreateWriteToolDefinition,\n\ttype WriteOperations,\n\ttype WriteToolInput,\n\ttype WriteToolOptions,\n} from \"./write.ts\";\n\nimport type { AgentTool } from \"@earendil-works/pi-agent-core\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { type BashToolOptions, createBashTool, createBashToolDefinition } from \"./bash.ts\";\nimport { createEditTool, createEditToolDefinition, type EditToolOptions } from \"./edit.ts\";\nimport { createFindTool, createFindToolDefinition, type FindToolOptions } from \"./find.ts\";\nimport { createGrepTool, createGrepToolDefinition, type GrepToolOptions } from \"./grep.ts\";\nimport { createLsTool, createLsToolDefinition, type LsToolOptions } from \"./ls.ts\";\nimport { createReadTool, createReadToolDefinition, type ReadToolOptions } from \"./read.ts\";\nimport { createWriteTool, createWriteToolDefinition, type WriteToolOptions } from \"./write.ts\";\n\nexport type Tool = AgentTool<any>;\nexport type ToolDef = ToolDefinition<any, any>;\nexport type ToolName = \"read\" | \"bash\" | \"edit\" | \"write\" | \"grep\" | \"find\" | \"ls\";\nexport const allToolNames: Set<ToolName> = new Set([\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"]);\n\nexport interface ToolsOptions {\n\tread?: ReadToolOptions;\n\tbash?: BashToolOptions;\n\twrite?: WriteToolOptions;\n\tedit?: EditToolOptions;\n\tgrep?: GrepToolOptions;\n\tfind?: FindToolOptions;\n\tls?: LsToolOptions;\n}\n\nexport function createAllToolDefinitions(cwd: string, options?: ToolsOptions): Record<ToolName, ToolDef> {\n\treturn {\n\t\tread: createReadToolDefinition(cwd, options?.read),\n\t\tbash: createBashToolDefinition(cwd, options?.bash),\n\t\tedit: createEditToolDefinition(cwd, options?.edit),\n\t\twrite: createWriteToolDefinition(cwd, options?.write),\n\t\tgrep: createGrepToolDefinition(cwd, options?.grep),\n\t\tfind: createFindToolDefinition(cwd, options?.find),\n\t\tls: createLsToolDefinition(cwd, options?.ls),\n\t};\n}\n\nexport function createCodingTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateBashTool(cwd, options?.bash),\n\t\tcreateEditTool(cwd, options?.edit),\n\t\tcreateWriteTool(cwd, options?.write),\n\t];\n}\n\nexport function createReadOnlyTools(cwd: string, options?: ToolsOptions): Tool[] {\n\treturn [\n\t\tcreateReadTool(cwd, options?.read),\n\t\tcreateGrepTool(cwd, options?.grep),\n\t\tcreateFindTool(cwd, options?.find),\n\t\tcreateLsTool(cwd, options?.ls),\n\t];\n}\n"]}
@@ -19,13 +19,10 @@ export interface OutputSnapshot {
19
19
  export declare class OutputAccumulator {
20
20
  private readonly maxLines;
21
21
  private readonly maxBytes;
22
- private readonly maxRollingBytes;
23
22
  private readonly tempFilePrefix;
24
23
  private readonly decoder;
24
+ private readonly tail;
25
25
  private rawChunks;
26
- private tailText;
27
- private tailBytes;
28
- private tailStartsAtLineBoundary;
29
26
  private totalRawBytes;
30
27
  private totalDecodedBytes;
31
28
  private completedLines;
@@ -37,6 +34,7 @@ export declare class OutputAccumulator {
37
34
  private tempFileStream;
38
35
  constructor(options?: OutputAccumulatorOptions);
39
36
  append(data: Buffer): void;
37
+ appendText(text: string): void;
40
38
  finish(): void;
41
39
  snapshot(options?: {
42
40
  persistIfTruncated?: boolean;
@@ -44,9 +42,9 @@ export declare class OutputAccumulator {
44
42
  closeTempFile(): Promise<void>;
45
43
  getLastLineBytes(): number;
46
44
  private appendDecodedText;
47
- private trimTail;
48
45
  private getSnapshotText;
49
46
  private shouldUseTempFile;
50
47
  private ensureTempFile;
48
+ private takeTempFileStream;
51
49
  }
52
50
  //# sourceMappingURL=output-accumulator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-accumulator.d.ts","sourceRoot":"","sources":["../../../src/core/tools/output-accumulator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAwC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAE1G,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAWD;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAE7C,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,wBAAwB,CAAQ;IACxC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAA0B;IAEhD,YAAY,OAAO,GAAE,wBAA6B,EAKjD;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAczB;IAED,MAAM,IAAI,IAAI,CASb;IAED,QAAQ,CAAC,OAAO,GAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,cAAc,CA4BvE;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBnC;IAED,gBAAgB,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,iBAAiB;IA+BzB,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,cAAc;CAWtB"}
1
+ {"version":3,"file":"output-accumulator.d.ts","sourceRoot":"","sources":["../../../src/core/tools/output-accumulator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAwC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAE1G,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAWD;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAElC,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAA0B;IAEhD,YAAY,OAAO,GAAE,wBAA6B,EAKjD;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAezB;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkB7B;IAED,MAAM,IAAI,IAAI,CAUb;IAED,QAAQ,CAAC,OAAO,GAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,cAAc,CA4BvE;IAEK,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBnC;IAED,gBAAgB,IAAI,MAAM,CAEzB;IAED,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,kBAAkB;CAK1B"}
@@ -2,6 +2,7 @@ import { randomBytes } from "node:crypto";
2
2
  import { createWriteStream } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
+ import { TailWindow } from "./tail-window.js";
5
6
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "./truncate.js";
6
7
  function defaultTempFilePath(prefix) {
7
8
  const id = randomBytes(8).toString("hex");
@@ -21,9 +22,6 @@ export class OutputAccumulator {
21
22
  constructor(options = {}) {
22
23
  this.decoder = new TextDecoder();
23
24
  this.rawChunks = [];
24
- this.tailText = "";
25
- this.tailBytes = 0;
26
- this.tailStartsAtLineBoundary = true;
27
25
  this.totalRawBytes = 0;
28
26
  this.totalDecodedBytes = 0;
29
27
  this.completedLines = 0;
@@ -33,15 +31,16 @@ export class OutputAccumulator {
33
31
  this.finished = false;
34
32
  this.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
35
33
  this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
36
- this.maxRollingBytes = Math.max(this.maxBytes * 2, 1);
37
34
  this.tempFilePrefix = options.tempFilePrefix ?? "pi-output";
35
+ this.tail = new TailWindow(Math.max(this.maxBytes * 2, 1));
38
36
  }
39
37
  append(data) {
40
38
  if (this.finished) {
41
39
  throw new Error("Cannot append to a finished output accumulator");
42
40
  }
41
+ const text = this.decoder.decode(data, { stream: true });
43
42
  this.totalRawBytes += data.length;
44
- this.appendDecodedText(this.decoder.decode(data, { stream: true }));
43
+ this.appendDecodedText(text, byteLength(text));
45
44
  if (this.tempFileStream || this.shouldUseTempFile()) {
46
45
  this.ensureTempFile();
47
46
  this.tempFileStream?.write(data);
@@ -50,12 +49,31 @@ export class OutputAccumulator {
50
49
  this.rawChunks.push(data);
51
50
  }
52
51
  }
52
+ appendText(text) {
53
+ if (this.finished) {
54
+ throw new Error("Cannot append to a finished output accumulator");
55
+ }
56
+ if (text.length === 0) {
57
+ return;
58
+ }
59
+ const bytes = byteLength(text);
60
+ this.totalRawBytes += bytes;
61
+ this.appendDecodedText(text, bytes);
62
+ if (this.tempFileStream || this.shouldUseTempFile()) {
63
+ this.ensureTempFile();
64
+ this.tempFileStream?.write(text);
65
+ }
66
+ else {
67
+ this.rawChunks.push(text);
68
+ }
69
+ }
53
70
  finish() {
54
71
  if (this.finished) {
55
72
  return;
56
73
  }
57
74
  this.finished = true;
58
- this.appendDecodedText(this.decoder.decode());
75
+ const finalText = this.decoder.decode();
76
+ this.appendDecodedText(finalText, byteLength(finalText));
59
77
  if (this.shouldUseTempFile()) {
60
78
  this.ensureTempFile();
61
79
  }
@@ -88,11 +106,10 @@ export class OutputAccumulator {
88
106
  };
89
107
  }
90
108
  async closeTempFile() {
91
- if (!this.tempFileStream) {
109
+ const stream = this.takeTempFileStream();
110
+ if (!stream) {
92
111
  return;
93
112
  }
94
- const stream = this.tempFileStream;
95
- this.tempFileStream = undefined;
96
113
  await new Promise((resolve, reject) => {
97
114
  const onError = (error) => {
98
115
  stream.off("finish", onFinish);
@@ -110,17 +127,12 @@ export class OutputAccumulator {
110
127
  getLastLineBytes() {
111
128
  return this.currentLineBytes;
112
129
  }
113
- appendDecodedText(text) {
130
+ appendDecodedText(text, bytes) {
114
131
  if (text.length === 0) {
115
132
  return;
116
133
  }
117
- const bytes = byteLength(text);
118
134
  this.totalDecodedBytes += bytes;
119
- this.tailText += text;
120
- this.tailBytes += bytes;
121
- if (this.tailBytes > this.maxRollingBytes * 2) {
122
- this.trimTail();
123
- }
135
+ this.tail.append(text, bytes, !this.hasOpenLine);
124
136
  let newlines = 0;
125
137
  let lastNewline = -1;
126
138
  for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1)) {
@@ -139,26 +151,13 @@ export class OutputAccumulator {
139
151
  }
140
152
  this.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);
141
153
  }
142
- trimTail() {
143
- const buffer = Buffer.from(this.tailText, "utf-8");
144
- if (buffer.length <= this.maxRollingBytes) {
145
- this.tailBytes = buffer.length;
146
- return;
147
- }
148
- let start = buffer.length - this.maxRollingBytes;
149
- while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {
150
- start++;
151
- }
152
- this.tailStartsAtLineBoundary = start === 0 ? this.tailStartsAtLineBoundary : buffer[start - 1] === 0x0a;
153
- this.tailText = buffer.subarray(start).toString("utf-8");
154
- this.tailBytes = byteLength(this.tailText);
155
- }
156
154
  getSnapshotText() {
157
- if (this.tailStartsAtLineBoundary) {
158
- return this.tailText;
155
+ const text = this.tail.text();
156
+ if (this.tail.startsAtLineBoundary) {
157
+ return text;
159
158
  }
160
- const firstNewline = this.tailText.indexOf("\n");
161
- return firstNewline === -1 ? this.tailText : this.tailText.slice(firstNewline + 1);
159
+ const firstNewline = text.indexOf("\n");
160
+ return firstNewline === -1 ? text : text.slice(firstNewline + 1);
162
161
  }
163
162
  shouldUseTempFile() {
164
163
  return (this.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines);
@@ -174,5 +173,10 @@ export class OutputAccumulator {
174
173
  }
175
174
  this.rawChunks = [];
176
175
  }
176
+ takeTempFileStream() {
177
+ const stream = this.tempFileStream;
178
+ this.tempFileStream = undefined;
179
+ return stream;
180
+ }
177
181
  }
178
182
  //# sourceMappingURL=output-accumulator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output-accumulator.js","sourceRoot":"","sources":["../../../src/core/tools/output-accumulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type TruncationResult, truncateTail } from \"./truncate.ts\";\n\nexport interface OutputAccumulatorOptions {\n\tmaxLines?: number;\n\tmaxBytes?: number;\n\ttempFilePrefix?: string;\n}\n\nexport interface OutputSnapshot {\n\tcontent: string;\n\ttruncation: TruncationResult;\n\tfullOutputPath?: string;\n}\n\nfunction defaultTempFilePath(prefix: string): string {\n\tconst id = randomBytes(8).toString(\"hex\");\n\treturn join(tmpdir(), `${prefix}-${id}.log`);\n}\n\nfunction byteLength(text: string): number {\n\treturn Buffer.byteLength(text, \"utf-8\");\n}\n\n/**\n * Incrementally tracks streaming output with bounded memory.\n *\n * Appends decode chunks with a streaming UTF-8 decoder, keeps only a decoded\n * tail for display snapshots, and opens a temp file when the full output needs\n * to be preserved.\n */\nexport class OutputAccumulator {\n\tprivate readonly maxLines: number;\n\tprivate readonly maxBytes: number;\n\tprivate readonly maxRollingBytes: number;\n\tprivate readonly tempFilePrefix: string;\n\tprivate readonly decoder = new TextDecoder();\n\n\tprivate rawChunks: Buffer[] = [];\n\tprivate tailText = \"\";\n\tprivate tailBytes = 0;\n\tprivate tailStartsAtLineBoundary = true;\n\tprivate totalRawBytes = 0;\n\tprivate totalDecodedBytes = 0;\n\tprivate completedLines = 0;\n\tprivate totalLines = 0;\n\tprivate currentLineBytes = 0;\n\tprivate hasOpenLine = false;\n\tprivate finished = false;\n\n\tprivate tempFilePath: string | undefined;\n\tprivate tempFileStream: WriteStream | undefined;\n\n\tconstructor(options: OutputAccumulatorOptions = {}) {\n\t\tthis.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\t\tthis.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\t\tthis.maxRollingBytes = Math.max(this.maxBytes * 2, 1);\n\t\tthis.tempFilePrefix = options.tempFilePrefix ?? \"pi-output\";\n\t}\n\n\tappend(data: Buffer): void {\n\t\tif (this.finished) {\n\t\t\tthrow new Error(\"Cannot append to a finished output accumulator\");\n\t\t}\n\n\t\tthis.totalRawBytes += data.length;\n\t\tthis.appendDecodedText(this.decoder.decode(data, { stream: true }));\n\n\t\tif (this.tempFileStream || this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t\tthis.tempFileStream?.write(data);\n\t\t} else if (data.length > 0) {\n\t\t\tthis.rawChunks.push(data);\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this.finished) {\n\t\t\treturn;\n\t\t}\n\t\tthis.finished = true;\n\t\tthis.appendDecodedText(this.decoder.decode());\n\t\tif (this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\t}\n\n\tsnapshot(options: { persistIfTruncated?: boolean } = {}): OutputSnapshot {\n\t\tconst tailTruncation = truncateTail(this.getSnapshotText(), {\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t});\n\t\tconst truncated = this.totalLines > this.maxLines || this.totalDecodedBytes > this.maxBytes;\n\t\tconst truncatedBy = truncated\n\t\t\t? (tailTruncation.truncatedBy ?? (this.totalDecodedBytes > this.maxBytes ? \"bytes\" : \"lines\"))\n\t\t\t: null;\n\t\tconst truncation: TruncationResult = {\n\t\t\t...tailTruncation,\n\t\t\ttruncated,\n\t\t\ttruncatedBy,\n\t\t\ttotalLines: this.totalLines,\n\t\t\ttotalBytes: this.totalDecodedBytes,\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t};\n\n\t\tif (options.persistIfTruncated && truncation.truncated) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: truncation.content,\n\t\t\ttruncation,\n\t\t\tfullOutputPath: this.tempFilePath,\n\t\t};\n\t}\n\n\tasync closeTempFile(): Promise<void> {\n\t\tif (!this.tempFileStream) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst stream = this.tempFileStream;\n\t\tthis.tempFileStream = undefined;\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tstream.off(\"finish\", onFinish);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tconst onFinish = () => {\n\t\t\t\tstream.off(\"error\", onError);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tstream.once(\"error\", onError);\n\t\t\tstream.once(\"finish\", onFinish);\n\t\t\tstream.end();\n\t\t});\n\t}\n\n\tgetLastLineBytes(): number {\n\t\treturn this.currentLineBytes;\n\t}\n\n\tprivate appendDecodedText(text: string): void {\n\t\tif (text.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst bytes = byteLength(text);\n\t\tthis.totalDecodedBytes += bytes;\n\t\tthis.tailText += text;\n\t\tthis.tailBytes += bytes;\n\t\tif (this.tailBytes > this.maxRollingBytes * 2) {\n\t\t\tthis.trimTail();\n\t\t}\n\n\t\tlet newlines = 0;\n\t\tlet lastNewline = -1;\n\t\tfor (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n\t\t\tnewlines++;\n\t\t\tlastNewline = i;\n\t\t}\n\t\tif (newlines === 0) {\n\t\t\tthis.currentLineBytes += bytes;\n\t\t\tthis.hasOpenLine = true;\n\t\t} else {\n\t\t\tthis.completedLines += newlines;\n\t\t\tconst tail = text.slice(lastNewline + 1);\n\t\t\tthis.currentLineBytes = byteLength(tail);\n\t\t\tthis.hasOpenLine = tail.length > 0;\n\t\t}\n\t\tthis.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);\n\t}\n\n\tprivate trimTail(): void {\n\t\tconst buffer = Buffer.from(this.tailText, \"utf-8\");\n\t\tif (buffer.length <= this.maxRollingBytes) {\n\t\t\tthis.tailBytes = buffer.length;\n\t\t\treturn;\n\t\t}\n\n\t\tlet start = buffer.length - this.maxRollingBytes;\n\t\twhile (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n\t\t\tstart++;\n\t\t}\n\n\t\tthis.tailStartsAtLineBoundary = start === 0 ? this.tailStartsAtLineBoundary : buffer[start - 1] === 0x0a;\n\t\tthis.tailText = buffer.subarray(start).toString(\"utf-8\");\n\t\tthis.tailBytes = byteLength(this.tailText);\n\t}\n\n\tprivate getSnapshotText(): string {\n\t\tif (this.tailStartsAtLineBoundary) {\n\t\t\treturn this.tailText;\n\t\t}\n\n\t\tconst firstNewline = this.tailText.indexOf(\"\\n\");\n\t\treturn firstNewline === -1 ? this.tailText : this.tailText.slice(firstNewline + 1);\n\t}\n\n\tprivate shouldUseTempFile(): boolean {\n\t\treturn (\n\t\t\tthis.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines\n\t\t);\n\t}\n\n\tprivate ensureTempFile(): void {\n\t\tif (this.tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tthis.tempFilePath = defaultTempFilePath(this.tempFilePrefix);\n\t\tthis.tempFileStream = createWriteStream(this.tempFilePath);\n\t\tfor (const chunk of this.rawChunks) {\n\t\t\tthis.tempFileStream.write(chunk);\n\t\t}\n\t\tthis.rawChunks = [];\n\t}\n}\n"]}
1
+ {"version":3,"file":"output-accumulator.js","sourceRoot":"","sources":["../../../src/core/tools/output-accumulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { TailWindow } from \"./tail-window.ts\";\nimport { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type TruncationResult, truncateTail } from \"./truncate.ts\";\n\nexport interface OutputAccumulatorOptions {\n\tmaxLines?: number;\n\tmaxBytes?: number;\n\ttempFilePrefix?: string;\n}\n\nexport interface OutputSnapshot {\n\tcontent: string;\n\ttruncation: TruncationResult;\n\tfullOutputPath?: string;\n}\n\nfunction defaultTempFilePath(prefix: string): string {\n\tconst id = randomBytes(8).toString(\"hex\");\n\treturn join(tmpdir(), `${prefix}-${id}.log`);\n}\n\nfunction byteLength(text: string): number {\n\treturn Buffer.byteLength(text, \"utf-8\");\n}\n\n/**\n * Incrementally tracks streaming output with bounded memory.\n *\n * Appends decode chunks with a streaming UTF-8 decoder, keeps only a decoded\n * tail for display snapshots, and opens a temp file when the full output needs\n * to be preserved.\n */\nexport class OutputAccumulator {\n\tprivate readonly maxLines: number;\n\tprivate readonly maxBytes: number;\n\tprivate readonly tempFilePrefix: string;\n\tprivate readonly decoder = new TextDecoder();\n\tprivate readonly tail: TailWindow;\n\n\tprivate rawChunks: Array<Buffer | string> = [];\n\tprivate totalRawBytes = 0;\n\tprivate totalDecodedBytes = 0;\n\tprivate completedLines = 0;\n\tprivate totalLines = 0;\n\tprivate currentLineBytes = 0;\n\tprivate hasOpenLine = false;\n\tprivate finished = false;\n\n\tprivate tempFilePath: string | undefined;\n\tprivate tempFileStream: WriteStream | undefined;\n\n\tconstructor(options: OutputAccumulatorOptions = {}) {\n\t\tthis.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;\n\t\tthis.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n\t\tthis.tempFilePrefix = options.tempFilePrefix ?? \"pi-output\";\n\t\tthis.tail = new TailWindow(Math.max(this.maxBytes * 2, 1));\n\t}\n\n\tappend(data: Buffer): void {\n\t\tif (this.finished) {\n\t\t\tthrow new Error(\"Cannot append to a finished output accumulator\");\n\t\t}\n\n\t\tconst text = this.decoder.decode(data, { stream: true });\n\t\tthis.totalRawBytes += data.length;\n\t\tthis.appendDecodedText(text, byteLength(text));\n\n\t\tif (this.tempFileStream || this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t\tthis.tempFileStream?.write(data);\n\t\t} else if (data.length > 0) {\n\t\t\tthis.rawChunks.push(data);\n\t\t}\n\t}\n\n\tappendText(text: string): void {\n\t\tif (this.finished) {\n\t\t\tthrow new Error(\"Cannot append to a finished output accumulator\");\n\t\t}\n\t\tif (text.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst bytes = byteLength(text);\n\t\tthis.totalRawBytes += bytes;\n\t\tthis.appendDecodedText(text, bytes);\n\n\t\tif (this.tempFileStream || this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t\tthis.tempFileStream?.write(text);\n\t\t} else {\n\t\t\tthis.rawChunks.push(text);\n\t\t}\n\t}\n\n\tfinish(): void {\n\t\tif (this.finished) {\n\t\t\treturn;\n\t\t}\n\t\tthis.finished = true;\n\t\tconst finalText = this.decoder.decode();\n\t\tthis.appendDecodedText(finalText, byteLength(finalText));\n\t\tif (this.shouldUseTempFile()) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\t}\n\n\tsnapshot(options: { persistIfTruncated?: boolean } = {}): OutputSnapshot {\n\t\tconst tailTruncation = truncateTail(this.getSnapshotText(), {\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t});\n\t\tconst truncated = this.totalLines > this.maxLines || this.totalDecodedBytes > this.maxBytes;\n\t\tconst truncatedBy = truncated\n\t\t\t? (tailTruncation.truncatedBy ?? (this.totalDecodedBytes > this.maxBytes ? \"bytes\" : \"lines\"))\n\t\t\t: null;\n\t\tconst truncation: TruncationResult = {\n\t\t\t...tailTruncation,\n\t\t\ttruncated,\n\t\t\ttruncatedBy,\n\t\t\ttotalLines: this.totalLines,\n\t\t\ttotalBytes: this.totalDecodedBytes,\n\t\t\tmaxLines: this.maxLines,\n\t\t\tmaxBytes: this.maxBytes,\n\t\t};\n\n\t\tif (options.persistIfTruncated && truncation.truncated) {\n\t\t\tthis.ensureTempFile();\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: truncation.content,\n\t\t\ttruncation,\n\t\t\tfullOutputPath: this.tempFilePath,\n\t\t};\n\t}\n\n\tasync closeTempFile(): Promise<void> {\n\t\tconst stream = this.takeTempFileStream();\n\t\tif (!stream) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst onError = (error: Error) => {\n\t\t\t\tstream.off(\"finish\", onFinish);\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\tconst onFinish = () => {\n\t\t\t\tstream.off(\"error\", onError);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\tstream.once(\"error\", onError);\n\t\t\tstream.once(\"finish\", onFinish);\n\t\t\tstream.end();\n\t\t});\n\t}\n\n\tgetLastLineBytes(): number {\n\t\treturn this.currentLineBytes;\n\t}\n\n\tprivate appendDecodedText(text: string, bytes: number): void {\n\t\tif (text.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.totalDecodedBytes += bytes;\n\t\tthis.tail.append(text, bytes, !this.hasOpenLine);\n\n\t\tlet newlines = 0;\n\t\tlet lastNewline = -1;\n\t\tfor (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n\t\t\tnewlines++;\n\t\t\tlastNewline = i;\n\t\t}\n\t\tif (newlines === 0) {\n\t\t\tthis.currentLineBytes += bytes;\n\t\t\tthis.hasOpenLine = true;\n\t\t} else {\n\t\t\tthis.completedLines += newlines;\n\t\t\tconst tail = text.slice(lastNewline + 1);\n\t\t\tthis.currentLineBytes = byteLength(tail);\n\t\t\tthis.hasOpenLine = tail.length > 0;\n\t\t}\n\t\tthis.totalLines = this.completedLines + (this.hasOpenLine ? 1 : 0);\n\t}\n\n\tprivate getSnapshotText(): string {\n\t\tconst text = this.tail.text();\n\t\tif (this.tail.startsAtLineBoundary) {\n\t\t\treturn text;\n\t\t}\n\n\t\tconst firstNewline = text.indexOf(\"\\n\");\n\t\treturn firstNewline === -1 ? text : text.slice(firstNewline + 1);\n\t}\n\n\tprivate shouldUseTempFile(): boolean {\n\t\treturn (\n\t\t\tthis.totalRawBytes > this.maxBytes || this.totalDecodedBytes > this.maxBytes || this.totalLines > this.maxLines\n\t\t);\n\t}\n\n\tprivate ensureTempFile(): void {\n\t\tif (this.tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tthis.tempFilePath = defaultTempFilePath(this.tempFilePrefix);\n\t\tthis.tempFileStream = createWriteStream(this.tempFilePath);\n\t\tfor (const chunk of this.rawChunks) {\n\t\t\tthis.tempFileStream.write(chunk);\n\t\t}\n\t\tthis.rawChunks = [];\n\t}\n\n\tprivate takeTempFileStream(): WriteStream | undefined {\n\t\tconst stream = this.tempFileStream;\n\t\tthis.tempFileStream = undefined;\n\t\treturn stream;\n\t}\n}\n"]}
@@ -0,0 +1,15 @@
1
+ export declare class TailWindow {
2
+ private readonly maxBytes;
3
+ private chunks;
4
+ private bytes;
5
+ private startsAtBoundary;
6
+ constructor(maxBytes: number);
7
+ append(text: string, bytes: number, startsAtLineBoundary: boolean): void;
8
+ text(): string;
9
+ get startsAtLineBoundary(): boolean;
10
+ private replaceWithTail;
11
+ private joined;
12
+ private compact;
13
+ private trimToMax;
14
+ }
15
+ //# sourceMappingURL=tail-window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tail-window.d.ts","sourceRoot":"","sources":["../../../src/core/tools/tail-window.ts"],"names":[],"mappings":"AAMA,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,gBAAgB,CAAQ;IAEhC,YAAY,QAAQ,EAAE,MAAM,EAE3B;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAG,IAAI,CAiBvE;IAED,IAAI,IAAI,MAAM,CAGb;IAED,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,SAAS;CAgBjB"}
@@ -0,0 +1,75 @@
1
+ const MAX_PENDING_TAIL_CHUNKS = 10;
2
+ function byteLength(text) {
3
+ return Buffer.byteLength(text, "utf-8");
4
+ }
5
+ export class TailWindow {
6
+ constructor(maxBytes) {
7
+ this.chunks = [];
8
+ this.bytes = 0;
9
+ this.startsAtBoundary = true;
10
+ this.maxBytes = maxBytes;
11
+ }
12
+ append(text, bytes, startsAtLineBoundary) {
13
+ if (bytes === 0) {
14
+ return;
15
+ }
16
+ if (bytes >= this.maxBytes) {
17
+ this.replaceWithTail(text, startsAtLineBoundary);
18
+ return;
19
+ }
20
+ this.chunks.push(text);
21
+ this.bytes += bytes;
22
+ if (this.chunks.length > MAX_PENDING_TAIL_CHUNKS) {
23
+ this.compact();
24
+ }
25
+ if (this.bytes > this.maxBytes * 2) {
26
+ this.trimToMax();
27
+ }
28
+ }
29
+ text() {
30
+ this.trimToMax();
31
+ return this.joined();
32
+ }
33
+ get startsAtLineBoundary() {
34
+ return this.startsAtBoundary;
35
+ }
36
+ replaceWithTail(text, startsAtLineBoundary) {
37
+ const buffer = Buffer.from(text, "utf-8");
38
+ let start = Math.max(0, buffer.length - this.maxBytes);
39
+ while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {
40
+ start++;
41
+ }
42
+ this.startsAtBoundary = start === 0 ? startsAtLineBoundary : buffer[start - 1] === 0x0a;
43
+ const tail = buffer.subarray(start).toString("utf-8");
44
+ this.chunks = tail.length > 0 ? [tail] : [];
45
+ this.bytes = byteLength(tail);
46
+ }
47
+ joined() {
48
+ if (this.chunks.length === 0) {
49
+ return "";
50
+ }
51
+ if (this.chunks.length > 1) {
52
+ this.compact();
53
+ }
54
+ return this.chunks[0] ?? "";
55
+ }
56
+ compact() {
57
+ const joined = this.chunks.join("");
58
+ this.chunks = joined.length > 0 ? [joined] : [];
59
+ }
60
+ trimToMax() {
61
+ if (this.bytes <= this.maxBytes) {
62
+ return;
63
+ }
64
+ const buffer = Buffer.from(this.joined(), "utf-8");
65
+ let start = Math.max(0, buffer.length - this.maxBytes);
66
+ while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {
67
+ start++;
68
+ }
69
+ this.startsAtBoundary = start === 0 ? this.startsAtBoundary : buffer[start - 1] === 0x0a;
70
+ const tail = buffer.subarray(start).toString("utf-8");
71
+ this.chunks = tail.length > 0 ? [tail] : [];
72
+ this.bytes = byteLength(tail);
73
+ }
74
+ }
75
+ //# sourceMappingURL=tail-window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tail-window.js","sourceRoot":"","sources":["../../../src/core/tools/tail-window.ts"],"names":[],"mappings":"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","sourcesContent":["const MAX_PENDING_TAIL_CHUNKS = 10;\n\nfunction byteLength(text: string): number {\n\treturn Buffer.byteLength(text, \"utf-8\");\n}\n\nexport class TailWindow {\n\tprivate readonly maxBytes: number;\n\tprivate chunks: string[] = [];\n\tprivate bytes = 0;\n\tprivate startsAtBoundary = true;\n\n\tconstructor(maxBytes: number) {\n\t\tthis.maxBytes = maxBytes;\n\t}\n\n\tappend(text: string, bytes: number, startsAtLineBoundary: boolean): void {\n\t\tif (bytes === 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (bytes >= this.maxBytes) {\n\t\t\tthis.replaceWithTail(text, startsAtLineBoundary);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.chunks.push(text);\n\t\tthis.bytes += bytes;\n\t\tif (this.chunks.length > MAX_PENDING_TAIL_CHUNKS) {\n\t\t\tthis.compact();\n\t\t}\n\t\tif (this.bytes > this.maxBytes * 2) {\n\t\t\tthis.trimToMax();\n\t\t}\n\t}\n\n\ttext(): string {\n\t\tthis.trimToMax();\n\t\treturn this.joined();\n\t}\n\n\tget startsAtLineBoundary(): boolean {\n\t\treturn this.startsAtBoundary;\n\t}\n\n\tprivate replaceWithTail(text: string, startsAtLineBoundary: boolean): void {\n\t\tconst buffer = Buffer.from(text, \"utf-8\");\n\t\tlet start = Math.max(0, buffer.length - this.maxBytes);\n\t\twhile (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n\t\t\tstart++;\n\t\t}\n\n\t\tthis.startsAtBoundary = start === 0 ? startsAtLineBoundary : buffer[start - 1] === 0x0a;\n\t\tconst tail = buffer.subarray(start).toString(\"utf-8\");\n\t\tthis.chunks = tail.length > 0 ? [tail] : [];\n\t\tthis.bytes = byteLength(tail);\n\t}\n\n\tprivate joined(): string {\n\t\tif (this.chunks.length === 0) {\n\t\t\treturn \"\";\n\t\t}\n\t\tif (this.chunks.length > 1) {\n\t\t\tthis.compact();\n\t\t}\n\t\treturn this.chunks[0] ?? \"\";\n\t}\n\n\tprivate compact(): void {\n\t\tconst joined = this.chunks.join(\"\");\n\t\tthis.chunks = joined.length > 0 ? [joined] : [];\n\t}\n\n\tprivate trimToMax(): void {\n\t\tif (this.bytes <= this.maxBytes) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst buffer = Buffer.from(this.joined(), \"utf-8\");\n\t\tlet start = Math.max(0, buffer.length - this.maxBytes);\n\t\twhile (start < buffer.length && (buffer[start] & 0xc0) === 0x80) {\n\t\t\tstart++;\n\t\t}\n\n\t\tthis.startsAtBoundary = start === 0 ? this.startsAtBoundary : buffer[start - 1] === 0x0a;\n\t\tconst tail = buffer.subarray(start).toString(\"utf-8\");\n\t\tthis.chunks = tail.length > 0 ? [tail] : [];\n\t\tthis.bytes = byteLength(tail);\n\t}\n}\n"]}
@@ -13,13 +13,18 @@ export interface ProjectTrustOption {
13
13
  updates: ProjectTrustUpdate[];
14
14
  savedPath?: string;
15
15
  }
16
- export declare function getProjectTrustPath(cwd: string): string;
17
16
  export declare function getProjectTrustParentPath(cwd: string): string | undefined;
18
17
  export declare function getProjectTrustOptions(cwd: string, options?: {
19
18
  includeSessionOnly?: boolean;
20
19
  }): ProjectTrustOption[];
21
- export declare function hasProjectConfigDir(cwd: string): boolean;
22
- export declare function hasProjectTrustInputs(cwd: string): boolean;
20
+ /**
21
+ * Returns true when cwd has project-local resources that must be gated by
22
+ * project trust: trust-requiring entries under cwd/.pi, or .agents/skills in
23
+ * cwd or one of its ancestors. Returns false when no such project resources
24
+ * exist. The user/global ~/.agents/skills directory is always treated as a
25
+ * trusted user resource and is ignored here, even when cwd is $HOME.
26
+ */
27
+ export declare function hasTrustRequiringProjectResources(cwd: string): boolean;
23
28
  export declare class ProjectTrustStore {
24
29
  private trustPath;
25
30
  constructor(agentDir: string);
@@ -1 +1 @@
1
- {"version":3,"file":"trust-manager.d.ts","sourceRoot":"","sources":["../../src/core/trust-manager.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAwBD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIzE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,kBAAkB,EAAE,CA8BpH;AAkFD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAiB1D;AAED,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,SAAS,CAAS;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAE3B;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAErC;IAED,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAKnD;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAErD;IAED,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAa7C;CACD"}
1
+ {"version":3,"file":"trust-manager.d.ts","sourceRoot":"","sources":["../../src/core/trust-manager.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAkCD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIzE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,kBAAkB,EAAE,CA8BpH;AAkFD;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAsBtE;AAED,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,SAAS,CAAS;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAE3B;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAErC;IAED,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAKnD;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAErD;IAED,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAa7C;CACD"}
@@ -1,8 +1,18 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
2
3
  import { dirname, join } from "node:path";
3
4
  import lockfile from "proper-lockfile";
4
5
  import { CONFIG_DIR_NAME } from "../config.js";
5
6
  import { canonicalizePath, resolvePath } from "../utils/paths.js";
7
+ const TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES = [
8
+ "settings.json",
9
+ "extensions",
10
+ "skills",
11
+ "prompts",
12
+ "themes",
13
+ "SYSTEM.md",
14
+ "APPEND_SYSTEM.md",
15
+ ];
6
16
  function normalizeCwd(cwd) {
7
17
  return canonicalizePath(resolvePath(cwd));
8
18
  }
@@ -20,16 +30,13 @@ function findNearestTrustEntry(data, cwd) {
20
30
  currentDir = parentDir;
21
31
  }
22
32
  }
23
- export function getProjectTrustPath(cwd) {
24
- return normalizeCwd(cwd);
25
- }
26
33
  export function getProjectTrustParentPath(cwd) {
27
- const trustPath = getProjectTrustPath(cwd);
34
+ const trustPath = normalizeCwd(cwd);
28
35
  const parentDir = dirname(trustPath);
29
36
  return parentDir === trustPath ? undefined : parentDir;
30
37
  }
31
38
  export function getProjectTrustOptions(cwd, options) {
32
- const trustPath = getProjectTrustPath(cwd);
39
+ const trustPath = normalizeCwd(cwd);
33
40
  const trustOptions = [
34
41
  { label: "Trust", trusted: true, updates: [{ path: trustPath, decision: true }], savedPath: trustPath },
35
42
  ];
@@ -132,16 +139,24 @@ function withTrustFileLock(path, fn) {
132
139
  release();
133
140
  }
134
141
  }
135
- export function hasProjectConfigDir(cwd) {
136
- return existsSync(join(canonicalizePath(resolvePath(cwd)), CONFIG_DIR_NAME));
137
- }
138
- export function hasProjectTrustInputs(cwd) {
142
+ /**
143
+ * Returns true when cwd has project-local resources that must be gated by
144
+ * project trust: trust-requiring entries under cwd/.pi, or .agents/skills in
145
+ * cwd or one of its ancestors. Returns false when no such project resources
146
+ * exist. The user/global ~/.agents/skills directory is always treated as a
147
+ * trusted user resource and is ignored here, even when cwd is $HOME.
148
+ */
149
+ export function hasTrustRequiringProjectResources(cwd) {
150
+ const homeDir = canonicalizePath(resolvePath(process.env.HOME || homedir()));
151
+ const userAgentsSkillsDir = join(homeDir, ".agents", "skills");
139
152
  let currentDir = canonicalizePath(resolvePath(cwd));
140
- if (hasProjectConfigDir(currentDir)) {
153
+ const configDir = join(currentDir, CONFIG_DIR_NAME);
154
+ if (TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some((entry) => existsSync(join(configDir, entry)))) {
141
155
  return true;
142
156
  }
143
157
  while (true) {
144
- if (existsSync(join(currentDir, ".agents", "skills"))) {
158
+ const agentsSkillsDir = join(currentDir, ".agents", "skills");
159
+ if (agentsSkillsDir !== userAgentsSkillsDir && existsSync(agentsSkillsDir)) {
145
160
  return true;
146
161
  }
147
162
  const parentDir = dirname(currentDir);