pulseed 0.4.14 → 0.4.16

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 (367) hide show
  1. package/assets/seedy.png +0 -0
  2. package/dist/adapters/agents/openai-codex.d.ts +2 -2
  3. package/dist/adapters/agents/openai-codex.js +2 -2
  4. package/dist/adapters/agents/openai-codex.js.map +1 -1
  5. package/dist/adapters/types/mcp.d.ts +6 -6
  6. package/dist/base/config/global-config.d.ts +44 -0
  7. package/dist/base/config/global-config.d.ts.map +1 -1
  8. package/dist/base/config/global-config.js +39 -2
  9. package/dist/base/config/global-config.js.map +1 -1
  10. package/dist/base/config/tool-metadata.d.ts +1 -1
  11. package/dist/base/config/tool-metadata.d.ts.map +1 -1
  12. package/dist/base/config/tool-metadata.js +21 -0
  13. package/dist/base/config/tool-metadata.js.map +1 -1
  14. package/dist/base/llm/codex-llm-client.d.ts +7 -1
  15. package/dist/base/llm/codex-llm-client.d.ts.map +1 -1
  16. package/dist/base/llm/codex-llm-client.js +10 -4
  17. package/dist/base/llm/codex-llm-client.js.map +1 -1
  18. package/dist/base/llm/provider-config.d.ts +8 -1
  19. package/dist/base/llm/provider-config.d.ts.map +1 -1
  20. package/dist/base/llm/provider-config.js +156 -94
  21. package/dist/base/llm/provider-config.js.map +1 -1
  22. package/dist/base/llm/provider-factory.d.ts.map +1 -1
  23. package/dist/base/llm/provider-factory.js +15 -0
  24. package/dist/base/llm/provider-factory.js.map +1 -1
  25. package/dist/base/utils/json-io.d.ts +6 -1
  26. package/dist/base/utils/json-io.d.ts.map +1 -1
  27. package/dist/base/utils/json-io.js +16 -3
  28. package/dist/base/utils/json-io.js.map +1 -1
  29. package/dist/interface/chat/chat-history.d.ts +7 -1
  30. package/dist/interface/chat/chat-history.d.ts.map +1 -1
  31. package/dist/interface/chat/chat-history.js +35 -2
  32. package/dist/interface/chat/chat-history.js.map +1 -1
  33. package/dist/interface/chat/chat-runner.d.ts +33 -1
  34. package/dist/interface/chat/chat-runner.d.ts.map +1 -1
  35. package/dist/interface/chat/chat-runner.js +559 -7
  36. package/dist/interface/chat/chat-runner.js.map +1 -1
  37. package/dist/interface/chat/grounding.d.ts.map +1 -1
  38. package/dist/interface/chat/grounding.js +2 -1
  39. package/dist/interface/chat/grounding.js.map +1 -1
  40. package/dist/interface/chat/mutation-tool-defs.d.ts +22 -9
  41. package/dist/interface/chat/mutation-tool-defs.d.ts.map +1 -1
  42. package/dist/interface/chat/mutation-tool-defs.js +26 -42
  43. package/dist/interface/chat/mutation-tool-defs.js.map +1 -1
  44. package/dist/interface/chat/self-knowledge-tools.d.ts +4 -0
  45. package/dist/interface/chat/self-knowledge-tools.d.ts.map +1 -1
  46. package/dist/interface/chat/self-knowledge-tools.js +16 -6
  47. package/dist/interface/chat/self-knowledge-tools.js.map +1 -1
  48. package/dist/interface/cli/commands/daemon.d.ts.map +1 -1
  49. package/dist/interface/cli/commands/daemon.js +4 -14
  50. package/dist/interface/cli/commands/daemon.js.map +1 -1
  51. package/dist/interface/cli/commands/setup/import/apply.d.ts.map +1 -1
  52. package/dist/interface/cli/commands/setup/import/apply.js +4 -0
  53. package/dist/interface/cli/commands/setup/import/apply.js.map +1 -1
  54. package/dist/interface/cli/commands/setup/import/discovery.d.ts.map +1 -1
  55. package/dist/interface/cli/commands/setup/import/discovery.js +10 -2
  56. package/dist/interface/cli/commands/setup/import/discovery.js.map +1 -1
  57. package/dist/interface/cli/commands/setup/import/flow.d.ts.map +1 -1
  58. package/dist/interface/cli/commands/setup/import/flow.js +11 -1
  59. package/dist/interface/cli/commands/setup/import/flow.js.map +1 -1
  60. package/dist/interface/cli/commands/setup/import/types.d.ts +3 -0
  61. package/dist/interface/cli/commands/setup/import/types.d.ts.map +1 -1
  62. package/dist/interface/cli/commands/setup-wizard.d.ts.map +1 -1
  63. package/dist/interface/cli/commands/setup-wizard.js +14 -1
  64. package/dist/interface/cli/commands/setup-wizard.js.map +1 -1
  65. package/dist/interface/cli/setup.d.ts.map +1 -1
  66. package/dist/interface/cli/setup.js +6 -5
  67. package/dist/interface/cli/setup.js.map +1 -1
  68. package/dist/interface/mcp-server/index.d.ts.map +1 -1
  69. package/dist/interface/mcp-server/index.js +2 -1
  70. package/dist/interface/mcp-server/index.js.map +1 -1
  71. package/dist/interface/tui/app.d.ts +8 -0
  72. package/dist/interface/tui/app.d.ts.map +1 -1
  73. package/dist/interface/tui/app.js +50 -27
  74. package/dist/interface/tui/app.js.map +1 -1
  75. package/dist/interface/tui/chat.d.ts +2 -1
  76. package/dist/interface/tui/chat.d.ts.map +1 -1
  77. package/dist/interface/tui/chat.js +17 -22
  78. package/dist/interface/tui/chat.js.map +1 -1
  79. package/dist/interface/tui/clipboard.d.ts.map +1 -1
  80. package/dist/interface/tui/clipboard.js +2 -1
  81. package/dist/interface/tui/clipboard.js.map +1 -1
  82. package/dist/interface/tui/cursor-tracker.d.ts +4 -4
  83. package/dist/interface/tui/cursor-tracker.d.ts.map +1 -1
  84. package/dist/interface/tui/cursor-tracker.js +6 -10
  85. package/dist/interface/tui/cursor-tracker.js.map +1 -1
  86. package/dist/interface/tui/entry.d.ts.map +1 -1
  87. package/dist/interface/tui/entry.js +198 -154
  88. package/dist/interface/tui/entry.js.map +1 -1
  89. package/dist/interface/tui/flicker/AlternateScreen.d.ts +2 -1
  90. package/dist/interface/tui/flicker/AlternateScreen.d.ts.map +1 -1
  91. package/dist/interface/tui/flicker/AlternateScreen.js +5 -4
  92. package/dist/interface/tui/flicker/AlternateScreen.js.map +1 -1
  93. package/dist/interface/tui/flicker/MouseTracking.d.ts +2 -1
  94. package/dist/interface/tui/flicker/MouseTracking.d.ts.map +1 -1
  95. package/dist/interface/tui/flicker/MouseTracking.js +4 -3
  96. package/dist/interface/tui/flicker/MouseTracking.js.map +1 -1
  97. package/dist/interface/tui/flicker/frame-writer.js +3 -3
  98. package/dist/interface/tui/flicker/frame-writer.js.map +1 -1
  99. package/dist/interface/tui/fullscreen-chat.d.ts +3 -1
  100. package/dist/interface/tui/fullscreen-chat.d.ts.map +1 -1
  101. package/dist/interface/tui/fullscreen-chat.js +47 -44
  102. package/dist/interface/tui/fullscreen-chat.js.map +1 -1
  103. package/dist/interface/tui/git-branch.d.ts +2 -0
  104. package/dist/interface/tui/git-branch.d.ts.map +1 -0
  105. package/dist/interface/tui/git-branch.js +14 -0
  106. package/dist/interface/tui/git-branch.js.map +1 -0
  107. package/dist/interface/tui/output-controller.d.ts +10 -0
  108. package/dist/interface/tui/output-controller.d.ts.map +1 -0
  109. package/dist/interface/tui/output-controller.js +79 -0
  110. package/dist/interface/tui/output-controller.js.map +1 -0
  111. package/dist/interface/tui/terminal-output.d.ts +6 -0
  112. package/dist/interface/tui/terminal-output.d.ts.map +1 -0
  113. package/dist/interface/tui/terminal-output.js +11 -0
  114. package/dist/interface/tui/terminal-output.js.map +1 -0
  115. package/dist/interface/tui/test-app.d.ts +2 -1
  116. package/dist/interface/tui/test-app.d.ts.map +1 -1
  117. package/dist/interface/tui/test-app.js +2 -2
  118. package/dist/interface/tui/test-app.js.map +1 -1
  119. package/dist/interface/tui/test-entry.d.ts.map +1 -1
  120. package/dist/interface/tui/test-entry.js +40 -42
  121. package/dist/interface/tui/test-entry.js.map +1 -1
  122. package/dist/interface/tui/text-width.d.ts +3 -0
  123. package/dist/interface/tui/text-width.d.ts.map +1 -0
  124. package/dist/interface/tui/text-width.js +8 -0
  125. package/dist/interface/tui/text-width.js.map +1 -0
  126. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.d.ts +4 -1
  127. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.d.ts.map +1 -1
  128. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.js +29 -5
  129. package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.js.map +1 -1
  130. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.d.ts +3 -0
  131. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.d.ts.map +1 -1
  132. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.js +13 -0
  133. package/dist/orchestrator/execution/agent-loop/agent-loop-prompts.js.map +1 -1
  134. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts +5 -1
  135. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts.map +1 -1
  136. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js +4 -0
  137. package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js.map +1 -1
  138. package/dist/orchestrator/execution/agent-loop/execution-policy.d.ts +26 -0
  139. package/dist/orchestrator/execution/agent-loop/execution-policy.d.ts.map +1 -0
  140. package/dist/orchestrator/execution/agent-loop/execution-policy.js +45 -0
  141. package/dist/orchestrator/execution/agent-loop/execution-policy.js.map +1 -0
  142. package/dist/orchestrator/execution/agent-loop/index.d.ts +1 -0
  143. package/dist/orchestrator/execution/agent-loop/index.d.ts.map +1 -1
  144. package/dist/orchestrator/execution/agent-loop/index.js +1 -0
  145. package/dist/orchestrator/execution/agent-loop/index.js.map +1 -1
  146. package/dist/orchestrator/execution/agent-loop/task-agent-loop-context.d.ts +2 -0
  147. package/dist/orchestrator/execution/agent-loop/task-agent-loop-context.d.ts.map +1 -1
  148. package/dist/orchestrator/execution/agent-loop/task-agent-loop-context.js +2 -0
  149. package/dist/orchestrator/execution/agent-loop/task-agent-loop-context.js.map +1 -1
  150. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.d.ts.map +1 -1
  151. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.js +11 -0
  152. package/dist/orchestrator/execution/agent-loop/task-agent-loop-factory.js.map +1 -1
  153. package/dist/orchestrator/execution/agent-loop/task-agent-loop-runner.d.ts +4 -0
  154. package/dist/orchestrator/execution/agent-loop/task-agent-loop-runner.d.ts.map +1 -1
  155. package/dist/orchestrator/execution/agent-loop/task-agent-loop-runner.js +3 -0
  156. package/dist/orchestrator/execution/agent-loop/task-agent-loop-runner.js.map +1 -1
  157. package/dist/orchestrator/execution/task/task-executor.d.ts.map +1 -1
  158. package/dist/orchestrator/execution/task/task-executor.js +9 -14
  159. package/dist/orchestrator/execution/task/task-executor.js.map +1 -1
  160. package/dist/platform/observation/observation-tools.d.ts.map +1 -1
  161. package/dist/platform/observation/observation-tools.js +4 -1
  162. package/dist/platform/observation/observation-tools.js.map +1 -1
  163. package/dist/platform/soil/config.d.ts.map +1 -1
  164. package/dist/platform/soil/config.js +1 -2
  165. package/dist/platform/soil/config.js.map +1 -1
  166. package/dist/platform/soil/contracts.d.ts +36 -36
  167. package/dist/platform/soil/display/index.d.ts +4 -0
  168. package/dist/platform/soil/display/index.d.ts.map +1 -0
  169. package/dist/platform/soil/display/index.js +4 -0
  170. package/dist/platform/soil/display/index.js.map +1 -0
  171. package/dist/platform/soil/display/materialize.d.ts +3 -0
  172. package/dist/platform/soil/display/materialize.d.ts.map +1 -0
  173. package/dist/platform/soil/display/materialize.js +381 -0
  174. package/dist/platform/soil/display/materialize.js.map +1 -0
  175. package/dist/platform/soil/display/registry.d.ts +4 -0
  176. package/dist/platform/soil/display/registry.d.ts.map +1 -0
  177. package/dist/platform/soil/display/registry.js +19 -0
  178. package/dist/platform/soil/display/registry.js.map +1 -0
  179. package/dist/platform/soil/display/types.d.ts +28 -0
  180. package/dist/platform/soil/display/types.d.ts.map +1 -0
  181. package/dist/platform/soil/display/types.js +2 -0
  182. package/dist/platform/soil/display/types.js.map +1 -0
  183. package/dist/platform/soil/index.d.ts +1 -0
  184. package/dist/platform/soil/index.d.ts.map +1 -1
  185. package/dist/platform/soil/index.js +1 -0
  186. package/dist/platform/soil/index.js.map +1 -1
  187. package/dist/platform/soil/open.d.ts.map +1 -1
  188. package/dist/platform/soil/open.js +2 -0
  189. package/dist/platform/soil/open.js.map +1 -1
  190. package/dist/platform/soil/publish/publisher.d.ts.map +1 -1
  191. package/dist/platform/soil/publish/publisher.js +2 -0
  192. package/dist/platform/soil/publish/publisher.js.map +1 -1
  193. package/dist/reflection/evening-catchup.d.ts.map +1 -1
  194. package/dist/reflection/evening-catchup.js +6 -41
  195. package/dist/reflection/evening-catchup.js.map +1 -1
  196. package/dist/reflection/morning-planning.d.ts.map +1 -1
  197. package/dist/reflection/morning-planning.js +6 -46
  198. package/dist/reflection/morning-planning.js.map +1 -1
  199. package/dist/reflection/reflection-utils.d.ts +16 -0
  200. package/dist/reflection/reflection-utils.d.ts.map +1 -0
  201. package/dist/reflection/reflection-utils.js +56 -0
  202. package/dist/reflection/reflection-utils.js.map +1 -0
  203. package/dist/reflection/weekly-review.d.ts.map +1 -1
  204. package/dist/reflection/weekly-review.js +3 -12
  205. package/dist/reflection/weekly-review.js.map +1 -1
  206. package/dist/reporting/report-formatters.d.ts +7 -0
  207. package/dist/reporting/report-formatters.d.ts.map +1 -1
  208. package/dist/reporting/report-formatters.js +22 -33
  209. package/dist/reporting/report-formatters.js.map +1 -1
  210. package/dist/reporting/reporting-engine.d.ts.map +1 -1
  211. package/dist/reporting/reporting-engine.js +34 -49
  212. package/dist/reporting/reporting-engine.js.map +1 -1
  213. package/dist/runtime/builtin-integrations.d.ts +4 -0
  214. package/dist/runtime/builtin-integrations.d.ts.map +1 -0
  215. package/dist/runtime/builtin-integrations.js +67 -0
  216. package/dist/runtime/builtin-integrations.js.map +1 -0
  217. package/dist/runtime/daemon/runner-lifecycle.d.ts +5 -0
  218. package/dist/runtime/daemon/runner-lifecycle.d.ts.map +1 -1
  219. package/dist/runtime/daemon/runner-lifecycle.js +6 -4
  220. package/dist/runtime/daemon/runner-lifecycle.js.map +1 -1
  221. package/dist/runtime/daemon/runner.d.ts +3 -0
  222. package/dist/runtime/daemon/runner.d.ts.map +1 -1
  223. package/dist/runtime/daemon/runner.js +1 -0
  224. package/dist/runtime/daemon/runner.js.map +1 -1
  225. package/dist/runtime/event/server.d.ts +1 -1
  226. package/dist/runtime/event/server.d.ts.map +1 -1
  227. package/dist/runtime/event/server.js +5 -27
  228. package/dist/runtime/event/server.js.map +1 -1
  229. package/dist/runtime/executor/loop-supervisor.d.ts.map +1 -1
  230. package/dist/runtime/executor/loop-supervisor.js +2 -2
  231. package/dist/runtime/executor/loop-supervisor.js.map +1 -1
  232. package/dist/runtime/foreign-plugins/compatibility.d.ts +7 -0
  233. package/dist/runtime/foreign-plugins/compatibility.d.ts.map +1 -0
  234. package/dist/runtime/foreign-plugins/compatibility.js +175 -0
  235. package/dist/runtime/foreign-plugins/compatibility.js.map +1 -0
  236. package/dist/runtime/foreign-plugins/index.d.ts +3 -0
  237. package/dist/runtime/foreign-plugins/index.d.ts.map +1 -0
  238. package/dist/runtime/foreign-plugins/index.js +2 -0
  239. package/dist/runtime/foreign-plugins/index.js.map +1 -0
  240. package/dist/runtime/foreign-plugins/types.d.ts +25 -0
  241. package/dist/runtime/foreign-plugins/types.d.ts.map +1 -0
  242. package/dist/runtime/foreign-plugins/types.js +2 -0
  243. package/dist/runtime/foreign-plugins/types.js.map +1 -0
  244. package/dist/runtime/interactive-automation/default-registry.d.ts +9 -0
  245. package/dist/runtime/interactive-automation/default-registry.d.ts.map +1 -0
  246. package/dist/runtime/interactive-automation/default-registry.js +24 -0
  247. package/dist/runtime/interactive-automation/default-registry.js.map +1 -0
  248. package/dist/runtime/interactive-automation/index.d.ts +9 -0
  249. package/dist/runtime/interactive-automation/index.d.ts.map +1 -0
  250. package/dist/runtime/interactive-automation/index.js +9 -0
  251. package/dist/runtime/interactive-automation/index.js.map +1 -0
  252. package/dist/runtime/interactive-automation/providers/anthropic-computer-use.d.ts +14 -0
  253. package/dist/runtime/interactive-automation/providers/anthropic-computer-use.d.ts.map +1 -0
  254. package/dist/runtime/interactive-automation/providers/anthropic-computer-use.js +33 -0
  255. package/dist/runtime/interactive-automation/providers/anthropic-computer-use.js.map +1 -0
  256. package/dist/runtime/interactive-automation/providers/codex-app.d.ts +29 -0
  257. package/dist/runtime/interactive-automation/providers/codex-app.d.ts.map +1 -0
  258. package/dist/runtime/interactive-automation/providers/codex-app.js +67 -0
  259. package/dist/runtime/interactive-automation/providers/codex-app.js.map +1 -0
  260. package/dist/runtime/interactive-automation/providers/manus-browser.d.ts +23 -0
  261. package/dist/runtime/interactive-automation/providers/manus-browser.d.ts.map +1 -0
  262. package/dist/runtime/interactive-automation/providers/manus-browser.js +88 -0
  263. package/dist/runtime/interactive-automation/providers/manus-browser.js.map +1 -0
  264. package/dist/runtime/interactive-automation/providers/noop.d.ts +21 -0
  265. package/dist/runtime/interactive-automation/providers/noop.d.ts.map +1 -0
  266. package/dist/runtime/interactive-automation/providers/noop.js +59 -0
  267. package/dist/runtime/interactive-automation/providers/noop.js.map +1 -0
  268. package/dist/runtime/interactive-automation/providers/perplexity-research.d.ts +25 -0
  269. package/dist/runtime/interactive-automation/providers/perplexity-research.d.ts.map +1 -0
  270. package/dist/runtime/interactive-automation/providers/perplexity-research.js +124 -0
  271. package/dist/runtime/interactive-automation/providers/perplexity-research.js.map +1 -0
  272. package/dist/runtime/interactive-automation/registry.d.ts +20 -0
  273. package/dist/runtime/interactive-automation/registry.d.ts.map +1 -0
  274. package/dist/runtime/interactive-automation/registry.js +55 -0
  275. package/dist/runtime/interactive-automation/registry.js.map +1 -0
  276. package/dist/runtime/interactive-automation/types.d.ts +132 -0
  277. package/dist/runtime/interactive-automation/types.d.ts.map +1 -0
  278. package/dist/runtime/interactive-automation/types.js +8 -0
  279. package/dist/runtime/interactive-automation/types.js.map +1 -0
  280. package/dist/runtime/schedule/engine.d.ts +12 -0
  281. package/dist/runtime/schedule/engine.d.ts.map +1 -1
  282. package/dist/runtime/schedule/engine.js +402 -243
  283. package/dist/runtime/schedule/engine.js.map +1 -1
  284. package/dist/runtime/types/builtin-integration.d.ts +13 -0
  285. package/dist/runtime/types/builtin-integration.d.ts.map +1 -0
  286. package/dist/runtime/types/builtin-integration.js +2 -0
  287. package/dist/runtime/types/builtin-integration.js.map +1 -0
  288. package/dist/tools/automation/InteractiveAutomationTools.d.ts +333 -0
  289. package/dist/tools/automation/InteractiveAutomationTools.d.ts.map +1 -0
  290. package/dist/tools/automation/InteractiveAutomationTools.js +424 -0
  291. package/dist/tools/automation/InteractiveAutomationTools.js.map +1 -0
  292. package/dist/tools/automation/index.d.ts +2 -0
  293. package/dist/tools/automation/index.d.ts.map +1 -0
  294. package/dist/tools/automation/index.js +2 -0
  295. package/dist/tools/automation/index.js.map +1 -0
  296. package/dist/tools/builtin/index.d.ts +6 -0
  297. package/dist/tools/builtin/index.d.ts.map +1 -1
  298. package/dist/tools/builtin/index.js +25 -0
  299. package/dist/tools/builtin/index.js.map +1 -1
  300. package/dist/tools/execution/SoilOpenTool/SoilOpenTool.d.ts +4 -4
  301. package/dist/tools/execution/SpawnSessionTool/SpawnSessionTool.d.ts +40 -8
  302. package/dist/tools/execution/SpawnSessionTool/SpawnSessionTool.d.ts.map +1 -1
  303. package/dist/tools/execution/SpawnSessionTool/SpawnSessionTool.js +28 -4
  304. package/dist/tools/execution/SpawnSessionTool/SpawnSessionTool.js.map +1 -1
  305. package/dist/tools/executor.d.ts.map +1 -1
  306. package/dist/tools/executor.js +18 -2
  307. package/dist/tools/executor.js.map +1 -1
  308. package/dist/tools/fs/FileEditTool/FileEditTool.js +1 -1
  309. package/dist/tools/fs/FileEditTool/FileEditTool.js.map +1 -1
  310. package/dist/tools/fs/FileValidationTool/FileValidationTool.d.ts +1 -1
  311. package/dist/tools/fs/FileValidationTool/FileValidationTool.d.ts.map +1 -1
  312. package/dist/tools/fs/FileValidationTool/FileValidationTool.js +3 -16
  313. package/dist/tools/fs/FileValidationTool/FileValidationTool.js.map +1 -1
  314. package/dist/tools/fs/FileValidationTool/protected-path-policy.d.ts +12 -0
  315. package/dist/tools/fs/FileValidationTool/protected-path-policy.d.ts.map +1 -0
  316. package/dist/tools/fs/FileValidationTool/protected-path-policy.js +58 -0
  317. package/dist/tools/fs/FileValidationTool/protected-path-policy.js.map +1 -0
  318. package/dist/tools/fs/FileWriteTool/FileWriteTool.js +1 -1
  319. package/dist/tools/fs/FileWriteTool/FileWriteTool.js.map +1 -1
  320. package/dist/tools/fs/GlobTool/GlobTool.js +1 -1
  321. package/dist/tools/fs/GlobTool/GlobTool.js.map +1 -1
  322. package/dist/tools/fs/GrepTool/GrepTool.js +1 -1
  323. package/dist/tools/fs/GrepTool/GrepTool.js.map +1 -1
  324. package/dist/tools/fs/JsonQueryTool/JsonQueryTool.js +1 -1
  325. package/dist/tools/fs/JsonQueryTool/JsonQueryTool.js.map +1 -1
  326. package/dist/tools/fs/ListDirTool/ListDirTool.js +1 -1
  327. package/dist/tools/fs/ListDirTool/ListDirTool.js.map +1 -1
  328. package/dist/tools/fs/ReadPulseedFileTool/ReadPulseedFileTool.d.ts.map +1 -1
  329. package/dist/tools/fs/ReadPulseedFileTool/ReadPulseedFileTool.js +21 -5
  330. package/dist/tools/fs/ReadPulseedFileTool/ReadPulseedFileTool.js.map +1 -1
  331. package/dist/tools/fs/ReadTool/ReadTool.js +1 -1
  332. package/dist/tools/fs/ReadTool/ReadTool.js.map +1 -1
  333. package/dist/tools/fs/WritePulseedFileTool/WritePulseedFileTool.d.ts.map +1 -1
  334. package/dist/tools/fs/WritePulseedFileTool/WritePulseedFileTool.js +61 -6
  335. package/dist/tools/fs/WritePulseedFileTool/WritePulseedFileTool.js.map +1 -1
  336. package/dist/tools/interaction/plan-utils.js +2 -2
  337. package/dist/tools/interaction/plan-utils.js.map +1 -1
  338. package/dist/tools/network/HttpFetchTool/HttpFetchTool.js +1 -1
  339. package/dist/tools/network/HttpFetchTool/HttpFetchTool.js.map +1 -1
  340. package/dist/tools/network/McpStdioTool/McpStdioTool.d.ts +8 -8
  341. package/dist/tools/network/WebSearchTool/WebSearchTool.d.ts.map +1 -1
  342. package/dist/tools/network/WebSearchTool/WebSearchTool.js +1 -0
  343. package/dist/tools/network/WebSearchTool/WebSearchTool.js.map +1 -1
  344. package/dist/tools/permission.d.ts +1 -0
  345. package/dist/tools/permission.d.ts.map +1 -1
  346. package/dist/tools/permission.js +33 -0
  347. package/dist/tools/permission.js.map +1 -1
  348. package/dist/tools/query/ConfigTool/ConfigTool.d.ts.map +1 -1
  349. package/dist/tools/query/ConfigTool/ConfigTool.js +4 -3
  350. package/dist/tools/query/ConfigTool/ConfigTool.js.map +1 -1
  351. package/dist/tools/query/PluginStateTool/PluginStateTool.d.ts.map +1 -1
  352. package/dist/tools/query/PluginStateTool/PluginStateTool.js +13 -2
  353. package/dist/tools/query/PluginStateTool/PluginStateTool.js.map +1 -1
  354. package/dist/tools/system/EnvTool/EnvTool.d.ts +4 -4
  355. package/dist/tools/system/ProcessSessionTool/ProcessSessionTool.d.ts +4 -4
  356. package/dist/tools/system/ShellTool/ShellTool.d.ts.map +1 -1
  357. package/dist/tools/system/ShellTool/ShellTool.js +6 -46
  358. package/dist/tools/system/ShellTool/ShellTool.js.map +1 -1
  359. package/dist/tools/system/ShellTool/command-policy.d.ts +14 -0
  360. package/dist/tools/system/ShellTool/command-policy.d.ts.map +1 -0
  361. package/dist/tools/system/ShellTool/command-policy.js +121 -0
  362. package/dist/tools/system/ShellTool/command-policy.js.map +1 -0
  363. package/dist/tools/types.d.ts +9 -0
  364. package/dist/tools/types.d.ts.map +1 -1
  365. package/dist/tools/types.js +2 -0
  366. package/dist/tools/types.js.map +1 -1
  367. package/package.json +5 -4
@@ -3,6 +3,11 @@
3
3
  // Central coordinator for 1-shot chat execution (Tier 1).
4
4
  // Bypasses TaskLifecycle — calls adapter.execute() directly.
5
5
  import { execFile } from "node:child_process";
6
+ import * as fsp from "node:fs/promises";
7
+ import * as path from "node:path";
8
+ import { getPulseedDirPath } from "../../base/utils/paths.js";
9
+ import { loadProviderConfig } from "../../base/llm/provider-config.js";
10
+ import { TaskSchema } from "../../base/types/task.js";
6
11
  import { ChatHistory } from "./chat-history.js";
7
12
  import { ChatSessionCatalog, ChatSessionSelectorError, } from "./chat-session-store.js";
8
13
  import { buildChatContext, resolveGitRoot } from "../../platform/observation/context-provider.js";
@@ -13,6 +18,7 @@ import { TendCommand } from "./tend-command.js";
13
18
  import { EventSubscriber } from "./event-subscriber.js";
14
19
  import { buildPromptedToolProtocolSystemPrompt, extractPromptedToolCalls, } from "../../orchestrator/execution/agent-loop/prompted-tool-protocol.js";
15
20
  import { recognizeRuntimeControlIntent } from "../../runtime/control/index.js";
21
+ import { resolveExecutionPolicy, summarizeExecutionPolicy, withExecutionPolicyOverrides, } from "../../orchestrator/execution/agent-loop/execution-policy.js";
16
22
  const DEFAULT_TIMEOUT_MS = 120_000;
17
23
  const MAX_VERIFY_RETRIES = 2;
18
24
  const MAX_TOOL_LOOPS = 5;
@@ -20,6 +26,7 @@ const ACTIVITY_PREVIEW_CHARS = 40;
20
26
  const DIRECT_ANSWER_MAX_TOKENS = 256;
21
27
  // ─── Command help text ───
22
28
  const COMMAND_HELP = `Available commands:
29
+ Session
23
30
  /help Show this help message
24
31
  /clear Clear conversation history
25
32
  /sessions List prior chat sessions
@@ -27,9 +34,31 @@ const COMMAND_HELP = `Available commands:
27
34
  /title <title> Rename the current session
28
35
  /resume [id|title] Resume native agentloop state for the current or selected session
29
36
  /cleanup [--dry-run] Clean up stale chat sessions
37
+ /compact Summarize older chat turns and keep the latest turns
30
38
  /exit Exit chat mode
39
+
40
+ Goals and tasks
41
+ /status [goal-id] Show active goal status, or one goal when an id is provided
42
+ /goals List goals
43
+ /tasks [goal-id] List tasks for a goal; uses the only active goal when unambiguous
44
+ /task <task-id> [goal-id]
45
+ Show one task; searches goals when no goal id is provided
31
46
  /track Promote session to Tier 2 goal pursuit (not yet implemented)
32
- /tend Generate a goal from chat history and start autonomous daemon execution`;
47
+ /tend Generate a goal from chat history and start autonomous daemon execution
48
+
49
+ Configuration
50
+ /config Show provider configuration with secrets masked
51
+ /model Show the active provider/model/adapter
52
+ /permissions [args] Show or update session execution policy
53
+ /plugins List installed plugins when plugin metadata is available
54
+
55
+ Review and branching
56
+ /review Show current diff summary and verification context
57
+ /fork [title] Fork the current chat session into a new session
58
+ /undo Remove the latest chat turn from session history
59
+
60
+ Deferred
61
+ /retry and /usage are intentionally not supported yet.`;
33
62
  // ─── Helpers ───
34
63
  function checkGitChanges(cwd) {
35
64
  return new Promise((resolve) => {
@@ -92,6 +121,7 @@ export class ChatRunner {
92
121
  onEvent = undefined;
93
122
  nativeAgentLoopStatePath = null;
94
123
  runtimeControlContext = null;
124
+ sessionExecutionPolicy = null;
95
125
  constructor(deps) {
96
126
  this.deps = deps;
97
127
  }
@@ -108,6 +138,7 @@ export class ChatRunner {
108
138
  this.sessionActive = true;
109
139
  this.nativeAgentLoopStatePath = `chat/agentloop/${sessionId}.state.json`;
110
140
  this.history.setAgentLoopStatePath(this.nativeAgentLoopStatePath);
141
+ this.sessionExecutionPolicy = null;
111
142
  }
112
143
  startSessionFromLoadedSession(session) {
113
144
  const chatSession = this.loadedSessionToChatSession(session);
@@ -116,6 +147,7 @@ export class ChatRunner {
116
147
  this.sessionActive = true;
117
148
  this.nativeAgentLoopStatePath = session.agentLoopStatePath ?? `chat/agentloop/${session.id}.state.json`;
118
149
  this.history.setAgentLoopStatePath(this.nativeAgentLoopStatePath);
150
+ this.sessionExecutionPolicy = null;
119
151
  }
120
152
  getSessionId() {
121
153
  return this.history?.getSessionId() ?? null;
@@ -165,6 +197,352 @@ export class ChatRunner {
165
197
  });
166
198
  return `Session ${session.id}${title} (${session.cwd})\n${lines.join("\n")}`;
167
199
  }
200
+ async loadGoals() {
201
+ const goalIds = await this.deps.stateManager.listGoalIds();
202
+ const goals = await Promise.all(goalIds.map((id) => this.deps.stateManager.loadGoal(id)));
203
+ return goals.filter((goal) => goal !== null);
204
+ }
205
+ async listAllGoalIds() {
206
+ const activeIds = await this.deps.stateManager.listGoalIds();
207
+ const archivedIds = await this.deps.stateManager.listArchivedGoals();
208
+ const recoverableArchivedIds = await this.listRecoverableArchivedGoalIds();
209
+ return [...new Set([...activeIds, ...archivedIds, ...recoverableArchivedIds])];
210
+ }
211
+ resolveStatePath(baseDir, ...segments) {
212
+ const base = path.resolve(baseDir);
213
+ const resolved = path.resolve(base, ...segments);
214
+ if (!resolved.startsWith(base + path.sep))
215
+ return null;
216
+ return resolved;
217
+ }
218
+ async listRecoverableArchivedGoalIds() {
219
+ const stateManager = this.deps.stateManager;
220
+ if (typeof stateManager.getBaseDir !== "function")
221
+ return [];
222
+ const archiveDir = this.resolveStatePath(stateManager.getBaseDir(), "archive");
223
+ if (archiveDir === null)
224
+ return [];
225
+ let entries = [];
226
+ try {
227
+ entries = await fsp.readdir(archiveDir, { withFileTypes: true });
228
+ }
229
+ catch {
230
+ return [];
231
+ }
232
+ const goalIds = [];
233
+ for (const entry of entries) {
234
+ if (!entry.isDirectory() || entry.name === ".staging")
235
+ continue;
236
+ try {
237
+ await fsp.access(path.join(archiveDir, entry.name, "goal", "goal.json"));
238
+ goalIds.push(entry.name);
239
+ }
240
+ catch {
241
+ continue;
242
+ }
243
+ }
244
+ return goalIds;
245
+ }
246
+ activeGoals(goals) {
247
+ return goals.filter((goal) => goal.status === "active" || goal.status === "waiting" || goal.loop_status === "running");
248
+ }
249
+ formatGoalLine(goal) {
250
+ const dimensions = goal.dimensions.length === 0
251
+ ? "no dimensions"
252
+ : goal.dimensions
253
+ .slice(0, 3)
254
+ .map((dimension) => `${dimension.name}: ${String(dimension.current_value)} target ${JSON.stringify(dimension.threshold)}`)
255
+ .join("; ");
256
+ return `${goal.id} - ${goal.title} [${goal.status}, loop ${goal.loop_status}] ${dimensions}`;
257
+ }
258
+ async handleStatus(args, start) {
259
+ if (args) {
260
+ const goal = await this.deps.stateManager.loadGoal(args);
261
+ if (!goal) {
262
+ return { success: false, output: `Goal not found: ${args}`, elapsed_ms: Date.now() - start };
263
+ }
264
+ const lines = [
265
+ `Goal status: ${goal.title}`,
266
+ `ID: ${goal.id}`,
267
+ `Status: ${goal.status}`,
268
+ `Loop: ${goal.loop_status}`,
269
+ `Updated: ${goal.updated_at}`,
270
+ `Children: ${goal.children_ids.length}`,
271
+ `Dimensions:`,
272
+ ...goal.dimensions.map((dimension) => `- ${dimension.name}: current=${String(dimension.current_value)}, threshold=${JSON.stringify(dimension.threshold)}, confidence=${dimension.confidence}`),
273
+ ];
274
+ return { success: true, output: lines.join("\n"), elapsed_ms: Date.now() - start };
275
+ }
276
+ const goals = await this.loadGoals();
277
+ const active = this.activeGoals(goals);
278
+ if (active.length === 0) {
279
+ return { success: true, output: "No active goals found.", elapsed_ms: Date.now() - start };
280
+ }
281
+ return {
282
+ success: true,
283
+ output: `Active goals:\n${active.map((goal) => this.formatGoalLine(goal)).join("\n")}`,
284
+ elapsed_ms: Date.now() - start,
285
+ };
286
+ }
287
+ async handleGoals(start) {
288
+ const goals = await this.loadGoals();
289
+ if (goals.length === 0) {
290
+ return { success: true, output: "No goals found.", elapsed_ms: Date.now() - start };
291
+ }
292
+ return {
293
+ success: true,
294
+ output: `Goals:\n${goals.map((goal) => this.formatGoalLine(goal)).join("\n")}`,
295
+ elapsed_ms: Date.now() - start,
296
+ };
297
+ }
298
+ async readTasksFromDir(tasksDir) {
299
+ let entries = [];
300
+ try {
301
+ entries = await fsp.readdir(tasksDir);
302
+ }
303
+ catch {
304
+ return [];
305
+ }
306
+ const tasks = [];
307
+ for (const entry of entries) {
308
+ if (!entry.endsWith(".json") || entry === "task-history.json" || entry === "last-failure-context.json")
309
+ continue;
310
+ let raw;
311
+ try {
312
+ raw = JSON.parse(await fsp.readFile(path.join(tasksDir, entry), "utf-8"));
313
+ }
314
+ catch {
315
+ continue;
316
+ }
317
+ const parsed = TaskSchema.safeParse(raw);
318
+ if (parsed.success)
319
+ tasks.push(parsed.data);
320
+ }
321
+ return tasks.sort((a, b) => (a.created_at < b.created_at ? 1 : -1));
322
+ }
323
+ async readTasksForGoal(goalId) {
324
+ const stateManager = this.deps.stateManager;
325
+ if (typeof stateManager.getBaseDir !== "function")
326
+ return [];
327
+ const baseDir = stateManager.getBaseDir();
328
+ const activeTasksDir = this.resolveStatePath(baseDir, "tasks", goalId);
329
+ const archiveTasksDir = this.resolveStatePath(baseDir, "archive", goalId, "tasks");
330
+ if (activeTasksDir === null || archiveTasksDir === null)
331
+ return [];
332
+ const activeTasks = await this.readTasksFromDir(activeTasksDir);
333
+ if (activeTasks.length > 0)
334
+ return activeTasks;
335
+ return this.readTasksFromDir(archiveTasksDir);
336
+ }
337
+ async resolveGoalForTasks(selector) {
338
+ if (selector)
339
+ return { goalId: selector };
340
+ const active = this.activeGoals(await this.loadGoals());
341
+ if (active.length === 1)
342
+ return { goalId: active[0].id };
343
+ if (active.length === 0)
344
+ return { error: "No active goals found. Use /tasks <goal-id>." };
345
+ return { error: "Multiple active goals found. Use /tasks <goal-id>." };
346
+ }
347
+ formatTaskLine(task) {
348
+ const verdict = task.verification_verdict ? `, verdict ${task.verification_verdict}` : "";
349
+ return `${task.id} - ${task.status}${verdict}: ${task.work_description}`;
350
+ }
351
+ async handleTasks(args, start) {
352
+ const resolved = await this.resolveGoalForTasks(args);
353
+ if (resolved.error || !resolved.goalId) {
354
+ return { success: false, output: resolved.error ?? "Usage: /tasks <goal-id>", elapsed_ms: Date.now() - start };
355
+ }
356
+ const tasks = await this.readTasksForGoal(resolved.goalId);
357
+ if (tasks.length === 0) {
358
+ return { success: true, output: `No tasks found for goal "${resolved.goalId}".`, elapsed_ms: Date.now() - start };
359
+ }
360
+ return {
361
+ success: true,
362
+ output: `Tasks for goal ${resolved.goalId}:\n${tasks.map((task) => this.formatTaskLine(task)).join("\n")}`,
363
+ elapsed_ms: Date.now() - start,
364
+ };
365
+ }
366
+ parseTaskArgs(args) {
367
+ const parts = args.split(/\s+/).filter(Boolean);
368
+ const goalFlagIndex = parts.indexOf("--goal");
369
+ if (goalFlagIndex >= 0) {
370
+ const goalId = parts[goalFlagIndex + 1];
371
+ parts.splice(goalFlagIndex, goalId ? 2 : 1);
372
+ return { taskId: parts[0], goalId };
373
+ }
374
+ return { taskId: parts[0], goalId: parts[1] };
375
+ }
376
+ async findTask(taskId, goalId) {
377
+ const goalIds = goalId ? [goalId] : await this.listAllGoalIds();
378
+ const matches = [];
379
+ for (const candidateGoalId of goalIds) {
380
+ let raw = null;
381
+ try {
382
+ raw = await this.deps.stateManager.readRaw(`tasks/${candidateGoalId}/${taskId}.json`);
383
+ }
384
+ catch {
385
+ raw = null;
386
+ }
387
+ if (!raw) {
388
+ const tasks = await this.readTasksForGoal(candidateGoalId);
389
+ const matched = tasks.find((task) => task.id === taskId || task.id.startsWith(taskId));
390
+ if (matched)
391
+ matches.push({ goalId: candidateGoalId, task: matched });
392
+ continue;
393
+ }
394
+ const parsed = TaskSchema.safeParse(raw);
395
+ if (parsed.success)
396
+ matches.push({ goalId: candidateGoalId, task: parsed.data });
397
+ }
398
+ return { task: matches.length === 1 ? matches[0].task : undefined, matches };
399
+ }
400
+ formatTask(task) {
401
+ const lines = [
402
+ `Task: ${task.id}`,
403
+ `Goal: ${task.goal_id}`,
404
+ `Status: ${task.status}`,
405
+ `Category: ${task.task_category}`,
406
+ `Created: ${task.created_at}`,
407
+ `Work: ${task.work_description}`,
408
+ `Approach: ${task.approach}`,
409
+ ];
410
+ if (task.started_at)
411
+ lines.push(`Started: ${task.started_at}`);
412
+ if (task.completed_at)
413
+ lines.push(`Completed: ${task.completed_at}`);
414
+ if (task.verification_verdict)
415
+ lines.push(`Verification: ${task.verification_verdict}`);
416
+ if (task.verification_evidence?.length)
417
+ lines.push(`Evidence: ${task.verification_evidence.join("; ")}`);
418
+ if (task.success_criteria.length > 0) {
419
+ lines.push("Success criteria:");
420
+ lines.push(...task.success_criteria.map((criterion) => `- ${criterion.description}`));
421
+ }
422
+ return lines.join("\n");
423
+ }
424
+ async handleTask(args, start) {
425
+ const { taskId, goalId } = this.parseTaskArgs(args);
426
+ if (!taskId) {
427
+ return { success: false, output: "Usage: /task <task-id> [goal-id]", elapsed_ms: Date.now() - start };
428
+ }
429
+ const found = await this.findTask(taskId, goalId);
430
+ if (found.matches.length > 1) {
431
+ return {
432
+ success: false,
433
+ output: `Task selector "${taskId}" matched multiple goals. Use /task ${taskId} <goal-id>.\n${found.matches.map((match) => `- ${match.goalId}`).join("\n")}`,
434
+ elapsed_ms: Date.now() - start,
435
+ };
436
+ }
437
+ if (!found.task) {
438
+ const suffix = goalId ? ` for goal "${goalId}"` : "";
439
+ return { success: false, output: `Task not found: ${taskId}${suffix}`, elapsed_ms: Date.now() - start };
440
+ }
441
+ return { success: true, output: this.formatTask(found.task), elapsed_ms: Date.now() - start };
442
+ }
443
+ providerConfigBaseDir() {
444
+ const stateManager = this.deps.stateManager;
445
+ return typeof stateManager.getBaseDir === "function" ? stateManager.getBaseDir() : getPulseedDirPath();
446
+ }
447
+ async readProviderConfigSummary() {
448
+ const config = await loadProviderConfig({
449
+ baseDir: this.providerConfigBaseDir(),
450
+ saveMigration: false,
451
+ });
452
+ return {
453
+ provider: config.provider,
454
+ model: config.model,
455
+ adapter: config.adapter,
456
+ light_model: config.light_model,
457
+ base_url: config.base_url,
458
+ codex_cli_path: config.codex_cli_path,
459
+ has_api_key: Boolean(config.api_key),
460
+ };
461
+ }
462
+ formatConfig(config) {
463
+ return Object.entries(config)
464
+ .filter(([, value]) => value !== undefined)
465
+ .map(([key, value]) => `${key}: ${typeof value === "string" && /key|token|secret/i.test(key) ? "[masked]" : String(value)}`)
466
+ .join("\n");
467
+ }
468
+ async handleConfig(start) {
469
+ const config = await this.readProviderConfigSummary();
470
+ return { success: true, output: `Provider configuration:\n${this.formatConfig(config)}`, elapsed_ms: Date.now() - start };
471
+ }
472
+ async handleModel(start) {
473
+ const config = await this.readProviderConfigSummary();
474
+ return {
475
+ success: true,
476
+ output: `Model: ${config.model}\nProvider: ${config.provider}\nAdapter: ${config.adapter}`,
477
+ elapsed_ms: Date.now() - start,
478
+ };
479
+ }
480
+ async handlePlugins(start) {
481
+ if (!this.deps.pluginLoader) {
482
+ return { success: true, output: "Plugin information is not available in this chat session.", elapsed_ms: Date.now() - start };
483
+ }
484
+ try {
485
+ const plugins = await this.deps.pluginLoader.loadAll();
486
+ if (plugins.length === 0) {
487
+ return { success: true, output: "No plugins found.", elapsed_ms: Date.now() - start };
488
+ }
489
+ return {
490
+ success: true,
491
+ output: `Plugins:\n${plugins.map((plugin) => `${plugin.name} - ${plugin.type ?? "unknown"} - ${plugin.enabled === false ? "disabled" : "enabled"}`).join("\n")}`,
492
+ elapsed_ms: Date.now() - start,
493
+ };
494
+ }
495
+ catch (err) {
496
+ const message = err instanceof Error ? err.message : String(err);
497
+ return { success: true, output: `Plugin information is unavailable: ${message}`, elapsed_ms: Date.now() - start };
498
+ }
499
+ }
500
+ deterministicChatSummary(messages) {
501
+ const lines = messages.map((message) => `${message.role}: ${message.content.replace(/\s+/g, " ").trim()}`);
502
+ return lines.join("\n").slice(0, 4_000);
503
+ }
504
+ async summarizeChatForCompaction(messages, existingSummary) {
505
+ const content = [
506
+ existingSummary ? `Previous summary:\n${existingSummary}` : "",
507
+ `Messages to summarize:\n${messages.map((message) => `${message.role}: ${message.content}`).join("\n")}`,
508
+ ].filter(Boolean).join("\n\n");
509
+ if (this.deps.llmClient) {
510
+ try {
511
+ const response = await this.deps.llmClient.sendMessage([
512
+ { role: "user", content: `Summarize this chat history for later continuation. Preserve decisions, open tasks, constraints, and user preferences. Keep it concise.\n\n${content}` },
513
+ ], { max_tokens: 700, model_tier: "light" });
514
+ if (response.content.trim())
515
+ return { summary: response.content.trim(), usedLlm: true };
516
+ }
517
+ catch {
518
+ // Fall back to deterministic summary below.
519
+ }
520
+ }
521
+ const fallback = [
522
+ existingSummary ? `Previous summary:\n${existingSummary}` : "",
523
+ "Extractive summary:",
524
+ this.deterministicChatSummary(messages),
525
+ ].filter(Boolean).join("\n\n");
526
+ return { summary: fallback, usedLlm: false };
527
+ }
528
+ async handleCompact(start) {
529
+ if (!this.history) {
530
+ return { success: false, output: "No active chat session to compact.", elapsed_ms: Date.now() - start };
531
+ }
532
+ const session = this.history.getSessionData();
533
+ if (session.messages.length <= 4) {
534
+ return { success: true, output: "Chat history is already compact. No messages were removed.", elapsed_ms: Date.now() - start };
535
+ }
536
+ const olderMessages = session.messages.slice(0, -4);
537
+ const { summary, usedLlm } = await this.summarizeChatForCompaction(olderMessages, session.compactionSummary);
538
+ const { before, after } = await this.history.compact(summary, 4);
539
+ const method = usedLlm ? "LLM summary" : "deterministic summary";
540
+ return {
541
+ success: true,
542
+ output: `Compacted chat history with ${method}. Persisted ${before} message(s) down to ${after}; the latest user/assistant turns were kept.`,
543
+ elapsed_ms: Date.now() - start,
544
+ };
545
+ }
168
546
  async handleCommand(input) {
169
547
  const trimmed = input.trim();
170
548
  if (!trimmed.startsWith("/"))
@@ -175,7 +553,7 @@ export class ChatRunner {
175
553
  return { success: true, output: COMMAND_HELP, elapsed_ms: Date.now() - start };
176
554
  }
177
555
  if (cmd === "/clear") {
178
- this.history?.clear();
556
+ await this.history?.clear();
179
557
  return { success: true, output: "Conversation history cleared.", elapsed_ms: Date.now() - start };
180
558
  }
181
559
  if (cmd === "/sessions") {
@@ -224,6 +602,42 @@ export class ChatRunner {
224
602
  elapsed_ms: Date.now() - start,
225
603
  };
226
604
  }
605
+ if (cmd === "/compact") {
606
+ return this.handleCompact(start);
607
+ }
608
+ if (cmd === "/status") {
609
+ return this.handleStatus(trimmed.slice("/status".length).trim(), start);
610
+ }
611
+ if (cmd === "/goals") {
612
+ return this.handleGoals(start);
613
+ }
614
+ if (cmd === "/tasks") {
615
+ return this.handleTasks(trimmed.slice("/tasks".length).trim(), start);
616
+ }
617
+ if (cmd === "/task") {
618
+ return this.handleTask(trimmed.slice("/task".length).trim(), start);
619
+ }
620
+ if (cmd === "/config") {
621
+ return this.handleConfig(start);
622
+ }
623
+ if (cmd === "/model") {
624
+ return this.handleModel(start);
625
+ }
626
+ if (cmd === "/permissions") {
627
+ return this.handlePermissions(trimmed.slice("/permissions".length).trim(), start);
628
+ }
629
+ if (cmd === "/plugins") {
630
+ return this.handlePlugins(start);
631
+ }
632
+ if (cmd === "/review") {
633
+ return this.handleReview(start);
634
+ }
635
+ if (cmd === "/fork") {
636
+ return this.handleFork(trimmed.slice("/fork".length).trim(), start);
637
+ }
638
+ if (cmd === "/undo") {
639
+ return this.handleUndo(start);
640
+ }
227
641
  if (cmd === "/exit") {
228
642
  return { success: true, output: "Exiting chat mode.", elapsed_ms: Date.now() - start };
229
643
  }
@@ -276,6 +690,114 @@ export class ChatRunner {
276
690
  };
277
691
  }
278
692
  }
693
+ async handlePermissions(args, start) {
694
+ const policy = await this.getSessionExecutionPolicy();
695
+ if (!args) {
696
+ return {
697
+ success: true,
698
+ output: summarizeExecutionPolicy(policy),
699
+ elapsed_ms: Date.now() - start,
700
+ };
701
+ }
702
+ const tokens = args.toLowerCase().split(/\s+/).filter(Boolean);
703
+ let nextPolicy = policy;
704
+ for (let index = 0; index < tokens.length; index++) {
705
+ const token = tokens[index];
706
+ if (token === "read-only" || token === "readonly" || token === "read_only") {
707
+ nextPolicy = withExecutionPolicyOverrides(nextPolicy, { sandboxMode: "read_only" });
708
+ continue;
709
+ }
710
+ if (token === "workspace-write" || token === "workspace_write") {
711
+ nextPolicy = withExecutionPolicyOverrides(nextPolicy, { sandboxMode: "workspace_write" });
712
+ continue;
713
+ }
714
+ if (token === "full-access" || token === "danger-full-access" || token === "danger_full_access") {
715
+ nextPolicy = withExecutionPolicyOverrides(nextPolicy, { sandboxMode: "danger_full_access" });
716
+ continue;
717
+ }
718
+ if (token === "network" && tokens[index + 1]) {
719
+ nextPolicy = withExecutionPolicyOverrides(nextPolicy, { networkAccess: tokens[index + 1] === "on" });
720
+ index += 1;
721
+ continue;
722
+ }
723
+ if (token === "approval" && tokens[index + 1]) {
724
+ const approvalPolicy = tokens[index + 1];
725
+ if (approvalPolicy === "never" || approvalPolicy === "on_request" || approvalPolicy === "untrusted") {
726
+ nextPolicy = withExecutionPolicyOverrides(nextPolicy, { approvalPolicy });
727
+ index += 1;
728
+ continue;
729
+ }
730
+ }
731
+ return {
732
+ success: false,
733
+ output: "Usage: /permissions [read-only|workspace-write|full-access] [network on|off] [approval on_request|never|untrusted]",
734
+ elapsed_ms: Date.now() - start,
735
+ };
736
+ }
737
+ this.sessionExecutionPolicy = nextPolicy;
738
+ return {
739
+ success: true,
740
+ output: summarizeExecutionPolicy(nextPolicy),
741
+ elapsed_ms: Date.now() - start,
742
+ };
743
+ }
744
+ async handleReview(start) {
745
+ const cwd = this.sessionCwd ?? process.cwd();
746
+ const diffStat = await checkGitChanges(cwd);
747
+ const policy = await this.getSessionExecutionPolicy();
748
+ const output = [
749
+ "Review summary",
750
+ diffStat ? diffStat : "No uncommitted changes detected.",
751
+ "",
752
+ "Execution policy",
753
+ summarizeExecutionPolicy(policy),
754
+ ].join("\n");
755
+ return { success: true, output, elapsed_ms: Date.now() - start };
756
+ }
757
+ async handleFork(title, start) {
758
+ const cwd = this.sessionCwd ?? process.cwd();
759
+ const sessionId = crypto.randomUUID();
760
+ const baseSession = this.history?.getSessionData() ?? {
761
+ id: sessionId,
762
+ cwd,
763
+ createdAt: new Date().toISOString(),
764
+ updatedAt: new Date().toISOString(),
765
+ messages: [],
766
+ };
767
+ const now = new Date().toISOString();
768
+ const forkedSession = {
769
+ ...baseSession,
770
+ id: sessionId,
771
+ createdAt: now,
772
+ updatedAt: now,
773
+ title: title || (baseSession.title ? `${baseSession.title} (fork)` : "Forked session"),
774
+ };
775
+ this.history = ChatHistory.fromSession(this.deps.stateManager, forkedSession);
776
+ this.sessionCwd = cwd;
777
+ this.sessionActive = true;
778
+ this.nativeAgentLoopStatePath = `chat/agentloop/${sessionId}.state.json`;
779
+ this.history.setAgentLoopStatePath(this.nativeAgentLoopStatePath);
780
+ await this.history.persist();
781
+ return {
782
+ success: true,
783
+ output: `Forked chat session as ${sessionId}.`,
784
+ elapsed_ms: Date.now() - start,
785
+ };
786
+ }
787
+ async handleUndo(start) {
788
+ if (!this.history) {
789
+ return { success: false, output: "No active chat session to undo.", elapsed_ms: Date.now() - start };
790
+ }
791
+ const removed = await this.history.removeLastTurn();
792
+ if (removed === 0) {
793
+ return { success: false, output: "No chat turn to undo.", elapsed_ms: Date.now() - start };
794
+ }
795
+ return {
796
+ success: true,
797
+ output: `Removed ${removed} message(s) from chat history. File changes were not reverted.`,
798
+ elapsed_ms: Date.now() - start,
799
+ };
800
+ }
279
801
  async handleTend(args, start) {
280
802
  if (!this.deps.llmClient) {
281
803
  return {
@@ -496,13 +1018,21 @@ export class ChatRunner {
496
1018
  this.cachedStaticSystemPrompt = "";
497
1019
  }
498
1020
  }
499
- // Build conversation history from prior turns (last 10)
1021
+ // Build conversation history from prior turns (last 10), including any manual compaction summary.
500
1022
  const messages = history.getMessages();
1023
+ const compactionSummary = history.getSessionData().compactionSummary;
501
1024
  const priorTurns = resumeOnly ? messages.slice(-10) : messages.slice(0, -1).slice(-10);
502
1025
  let historyBlock = "";
1026
+ const historySections = [];
1027
+ if (compactionSummary) {
1028
+ historySections.push(`Compacted previous conversation summary:\n${compactionSummary}`);
1029
+ }
503
1030
  if (priorTurns.length > 0) {
504
1031
  const lines = priorTurns.map((m) => `${m.role === "user" ? "User" : "Assistant"}: ${m.content}`).join("\n");
505
- historyBlock = `Previous conversation:\n${lines}\n\nCurrent message:\n`;
1032
+ historySections.push(`Previous conversation:\n${lines}`);
1033
+ }
1034
+ if (historySections.length > 0) {
1035
+ historyBlock = `${historySections.join("\n\n")}\n\nCurrent message:\n`;
506
1036
  }
507
1037
  const directAnswerRoute = !resumeOnly && !this.deps.chatAgentLoopRunner && this.deps.llmClient !== undefined && shouldUseDirectAnswerRoute(input);
508
1038
  const directPrompt = historyBlock ? `${historyBlock}${input}` : input;
@@ -570,6 +1100,13 @@ export class ChatRunner {
570
1100
  .filter((section) => section && section.trim().length > 0)
571
1101
  .join("\n\n")
572
1102
  .trim();
1103
+ const agentLoopSystemPrompt = [
1104
+ systemPrompt,
1105
+ compactionSummary ? `## Compacted Chat Summary\n${compactionSummary}` : "",
1106
+ ]
1107
+ .filter((section) => section && section.trim().length > 0)
1108
+ .join("\n\n")
1109
+ .trim();
573
1110
  const context = resumeOnly ? "" : await buildChatContext(input, gitRoot);
574
1111
  const basePrompt = resumeOnly ? "" : (context ? `${context}\n\n${input}` : input);
575
1112
  const prompt = historyBlock ? `${historyBlock}${basePrompt}` : basePrompt;
@@ -624,10 +1161,13 @@ export class ChatRunner {
624
1161
  }
625
1162
  return false;
626
1163
  },
1164
+ toolCallContext: {
1165
+ executionPolicy: await this.getSessionExecutionPolicy(),
1166
+ },
627
1167
  ...(this.nativeAgentLoopStatePath ? { resumeStatePath: this.nativeAgentLoopStatePath } : {}),
628
1168
  ...(resumeState ? { resumeState } : {}),
629
1169
  ...(resumeOnly ? { resumeOnly: true } : {}),
630
- ...(systemPrompt ? { systemPrompt } : {}),
1170
+ ...(agentLoopSystemPrompt ? { systemPrompt: agentLoopSystemPrompt } : {}),
631
1171
  });
632
1172
  const elapsed_ms = Date.now() - start;
633
1173
  if (result.output) {
@@ -806,7 +1346,7 @@ export class ChatRunner {
806
1346
  async executeWithTools(prompt, eventContext, assistantBuffer, systemPrompt) {
807
1347
  const llmClient = this.deps.llmClient;
808
1348
  const messages = [{ role: "user", content: prompt }];
809
- const toolCallContext = this.buildToolCallContext();
1349
+ const toolCallContext = await this.buildToolCallContext();
810
1350
  for (let loop = 0; loop < MAX_TOOL_LOOPS; loop++) {
811
1351
  // Recompute tools each iteration so newly activated deferred tools are included
812
1352
  const tools = this.deps.registry
@@ -1260,7 +1800,18 @@ export class ChatRunner {
1260
1800
  });
1261
1801
  }
1262
1802
  /** Build a ToolCallContext from ChatRunnerDeps for tool dispatch. */
1263
- buildToolCallContext() {
1803
+ async getSessionExecutionPolicy() {
1804
+ if (this.sessionExecutionPolicy)
1805
+ return this.sessionExecutionPolicy;
1806
+ const config = await loadProviderConfig({ saveMigration: false });
1807
+ this.sessionExecutionPolicy = resolveExecutionPolicy({
1808
+ workspaceRoot: this.sessionCwd ?? process.cwd(),
1809
+ security: config.agent_loop?.security,
1810
+ });
1811
+ return this.sessionExecutionPolicy;
1812
+ }
1813
+ async buildToolCallContext() {
1814
+ const executionPolicy = await this.getSessionExecutionPolicy();
1264
1815
  return {
1265
1816
  cwd: this.sessionCwd ?? process.cwd(),
1266
1817
  goalId: this.deps.goalId ?? "",
@@ -1272,6 +1823,7 @@ export class ChatRunner {
1272
1823
  }
1273
1824
  return false;
1274
1825
  },
1826
+ executionPolicy,
1275
1827
  };
1276
1828
  }
1277
1829
  }