@selesai/code 0.13.16 → 0.13.18

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 (467) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +2 -14
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.js +3 -9
  5. package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
  6. package/dist/bun/sandbox-env-setup.d.ts +1 -0
  7. package/dist/bun/sandbox-env-setup.js +3 -0
  8. package/dist/cli/auth-command.d.ts +23 -0
  9. package/dist/cli/auth-command.js +102 -0
  10. package/dist/cli/config-selector.js +2 -1
  11. package/dist/cli/setup.d.ts +1 -0
  12. package/dist/cli/setup.js +11 -0
  13. package/dist/cli.js +2 -14
  14. package/dist/config.d.ts +3 -2
  15. package/dist/config.js +9 -4
  16. package/dist/core/agent-session-runtime.js +15 -7
  17. package/dist/core/agent-session.d.ts +2 -6
  18. package/dist/core/agent-session.js +15 -4
  19. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  20. package/dist/core/compaction/branch-summarization.js +2 -1
  21. package/dist/core/extensions/loader.js +3 -0
  22. package/dist/core/extensions/types.d.ts +16 -2
  23. package/dist/core/http-dispatcher.js +2 -0
  24. package/dist/core/keybindings.d.ts +5 -0
  25. package/dist/core/keybindings.js +4 -0
  26. package/dist/core/messages.d.ts +1 -1
  27. package/dist/core/model-config.d.ts +15 -0
  28. package/dist/core/model-config.js +3 -0
  29. package/dist/core/model-runtime.d.ts +1 -0
  30. package/dist/core/model-runtime.js +5 -2
  31. package/dist/core/provider-composer.js +8 -2
  32. package/dist/core/session-export.d.ts +3 -0
  33. package/dist/core/session-export.js +31 -0
  34. package/dist/core/session-manager.d.ts +3 -2
  35. package/dist/core/session-manager.js +40 -13
  36. package/dist/core/skills.d.ts +1 -1
  37. package/dist/core/skills.js +4 -2
  38. package/dist/core/system-prompt.js +10 -10
  39. package/dist/core/tools/bash.js +3 -117
  40. package/dist/core/tools/edit.d.ts +1 -12
  41. package/dist/core/tools/edit.js +5 -163
  42. package/dist/core/tools/find.js +4 -55
  43. package/dist/core/tools/grep.js +4 -60
  44. package/dist/core/tools/ls.js +4 -49
  45. package/dist/core/tools/read.d.ts +4 -0
  46. package/dist/core/tools/read.js +10 -122
  47. package/dist/core/tools/renderers/bash.d.ts +11 -0
  48. package/dist/core/tools/renderers/bash.js +129 -0
  49. package/dist/core/tools/renderers/edit.d.ts +22 -0
  50. package/dist/core/tools/renderers/edit.js +166 -0
  51. package/dist/core/tools/renderers/find.d.ts +9 -0
  52. package/dist/core/tools/renderers/find.js +63 -0
  53. package/dist/core/tools/renderers/grep.d.ts +9 -0
  54. package/dist/core/tools/renderers/grep.js +68 -0
  55. package/dist/core/tools/renderers/index.d.ts +27 -0
  56. package/dist/core/tools/renderers/index.js +46 -0
  57. package/dist/core/tools/renderers/ls.d.ts +9 -0
  58. package/dist/core/tools/renderers/ls.js +57 -0
  59. package/dist/core/tools/renderers/read.d.ts +10 -0
  60. package/dist/core/tools/renderers/read.js +128 -0
  61. package/dist/core/tools/renderers/write.d.ts +9 -0
  62. package/dist/core/tools/renderers/write.js +152 -0
  63. package/dist/core/tools/write.js +5 -146
  64. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
  65. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  66. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  67. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  68. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  69. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  70. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  71. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  72. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  73. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  74. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  75. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  76. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  77. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  78. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  79. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  81. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  82. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  83. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  84. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  85. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  86. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  87. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  88. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  89. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  91. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  92. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  93. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  99. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  100. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  101. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  102. package/dist/extensions/pi-intercom/README.md +16 -2
  103. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  104. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  105. package/dist/extensions/pi-intercom/index.ts +1 -1
  106. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  107. package/dist/extensions/pi-intercom/package.json +1 -1
  108. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  109. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  110. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  111. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  112. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  113. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  114. package/dist/extensions/pi-subagents/README.md +3 -3
  115. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  116. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  117. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  118. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  119. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  120. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  121. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  122. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  123. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  124. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  125. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  126. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  127. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  128. package/dist/extensions/pi-subagents/package.json +6 -4
  129. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  130. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  131. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  135. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  136. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  137. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  138. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  139. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  140. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  141. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  142. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  143. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  144. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  145. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  146. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  147. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  148. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  149. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  150. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  151. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  152. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  153. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  154. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  155. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  156. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  157. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  158. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  159. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  160. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  161. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  162. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  163. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  164. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  165. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  166. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  167. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  168. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  169. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  170. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  171. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  172. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  176. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  177. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  178. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  179. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  180. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  181. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  182. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  183. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  184. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  185. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  186. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  188. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  189. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  190. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  191. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  192. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  193. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  194. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  201. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  202. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  203. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  204. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  205. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  206. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  207. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  208. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  209. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  210. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  211. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  212. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  213. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  214. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  215. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  216. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  219. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  220. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  221. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  222. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  223. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  224. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  225. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  226. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  228. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  229. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  230. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  231. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  232. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  233. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  234. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  235. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  236. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  237. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  238. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  239. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  240. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  241. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  242. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  243. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  244. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  245. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  250. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  251. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  252. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  256. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  257. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  258. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  259. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  260. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  261. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  262. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  263. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  264. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  265. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  266. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  267. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  268. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  269. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  270. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  271. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  272. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  273. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  275. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  276. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  277. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  278. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  279. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  280. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  281. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  282. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  283. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  284. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  285. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  286. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  287. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  288. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  289. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  290. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  291. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  292. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  294. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  295. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  296. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  297. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  298. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  299. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  300. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  301. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  302. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  303. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  304. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  305. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  306. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  307. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  308. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  309. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  310. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  311. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  312. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  313. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  314. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  315. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  316. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  317. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  318. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  319. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  320. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  321. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  322. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  323. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  324. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  325. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  326. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  327. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  328. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  329. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  330. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  331. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  332. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  333. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  334. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  335. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  336. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  337. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  338. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  339. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  340. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  341. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  342. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  343. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  344. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  345. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  346. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  347. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  348. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  349. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  350. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  351. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  352. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  353. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  354. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  355. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  356. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  357. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  358. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  359. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  360. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  361. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  362. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  363. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  364. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  365. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  366. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  367. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  368. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  369. package/dist/extensions/pi-zentui/README.md +17 -0
  370. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  371. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  372. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  373. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  374. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  375. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  376. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  377. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  378. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  379. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  381. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  382. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  383. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  384. package/dist/extensions/pi-zentui/package.json +7 -4
  385. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  386. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  387. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  388. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  389. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  390. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  391. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  392. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  393. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  394. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  395. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  396. package/dist/index.d.ts +1 -1
  397. package/dist/main.js +4 -1
  398. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  399. package/dist/modes/interactive/chat-viewport.js +27 -0
  400. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  401. package/dist/modes/interactive/components/assistant-message.js +30 -13
  402. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  403. package/dist/modes/interactive/components/custom-editor.js +39 -1
  404. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  405. package/dist/modes/interactive/components/index.d.ts +1 -1
  406. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  407. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  408. package/dist/modes/interactive/components/model-selector.js +19 -17
  409. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  410. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  411. package/dist/modes/interactive/components/settings-selector.js +128 -20
  412. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  413. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  414. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  415. package/dist/modes/interactive/components/status-indicator.js +10 -3
  416. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  417. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  418. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  419. package/dist/modes/interactive/components/tool-execution.js +35 -33
  420. package/dist/modes/interactive/components/trust-selector.js +2 -2
  421. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  422. package/dist/modes/interactive/interactive-mode.js +144 -80
  423. package/dist/modes/interactive/session-share.d.ts +15 -0
  424. package/dist/modes/interactive/session-share.js +183 -0
  425. package/dist/modes/interactive/theme/dark.json +2 -1
  426. package/dist/modes/interactive/theme/light.json +2 -1
  427. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  428. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  429. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  430. package/dist/modes/interactive/theme/theme-json.js +129 -0
  431. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  432. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  433. package/dist/modes/interactive/theme/theme.js +18 -119
  434. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  435. package/dist/modes/interactive/tui-renderer.js +65 -0
  436. package/dist/utils/exif-orientation.js +2 -3
  437. package/dist/utils/management-http.d.ts +24 -0
  438. package/dist/utils/management-http.js +53 -0
  439. package/dist/utils/text.d.ts +7 -0
  440. package/dist/utils/text.js +8 -0
  441. package/dist/utils/tools-manager.d.ts +1 -0
  442. package/dist/utils/tools-manager.js +43 -21
  443. package/docs/docs.json +0 -4
  444. package/package.json +4 -4
  445. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  446. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  447. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  448. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  449. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  450. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  451. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  452. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  453. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  454. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  455. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  456. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  457. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  458. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  459. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  460. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  461. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  462. package/dist/skills/implanger/SKILL.md +0 -70
  463. package/dist/skills/output/SKILL.md +0 -49
  464. package/dist/skills/planger/SKILL.md +0 -167
  465. package/dist/skills/workflow/SKILL.md +0 -95
  466. package/docs/workflows.md +0 -18
  467. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-hermes-memory",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "Bundled Selesai fork of pi-hermes-memory: persistent memory, session search, and secret scanning.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -51,15 +51,15 @@
51
51
  "@earendil-works/pi-coding-agent": ">=0.80.6"
52
52
  },
53
53
  "devDependencies": {
54
- "@earendil-works/pi-ai": "0.84.4",
55
- "@earendil-works/pi-coding-agent": "0.84.4",
54
+ "@earendil-works/pi-ai": "0.85.1",
55
+ "@earendil-works/pi-coding-agent": "0.85.1",
56
56
  "@types/better-sqlite3": "^7.6.13",
57
57
  "tsx": "^4.21.0",
58
58
  "typebox": "^1.1.33",
59
59
  "typescript": "^6.0.3"
60
60
  },
61
61
  "dependencies": {
62
- "@earendil-works/pi-tui": "0.84.4",
62
+ "@earendil-works/pi-tui": "0.85.1",
63
63
  "better-sqlite3": "^13.0.3",
64
64
  "strip-ansi": "7.2.0"
65
65
  }
@@ -15,6 +15,7 @@ import {
15
15
  DEFAULT_OVERFLOW_GRACE_MS,
16
16
  DEFAULT_FAILURE_INJECTION_MAX_AGE_DAYS,
17
17
  DEFAULT_FAILURE_INJECTION_MAX_ENTRIES,
18
+ DEFAULT_SESSION_RETENTION_DAYS,
18
19
  } from "./constants.js";
19
20
  import { AGENT_ROOT, normalizeConfiguredMemoryDir, normalizeProjectsMemoryDir } from "./paths.js";
20
21
 
@@ -66,6 +67,8 @@ const DEFAULT_CONFIG: MemoryConfig = {
66
67
  standingInstructionsEnabled: true,
67
68
  projectsMemoryDir: DEFAULT_PROJECTS_MEMORY_DIR,
68
69
  sessionSearch: { variant: "legacy" },
70
+ quickCheckOnOpen: true,
71
+ sessionRetentionDays: DEFAULT_SESSION_RETENTION_DAYS,
69
72
  };
70
73
 
71
74
  export const DEFAULT_CONFIG_PATH = path.join(
@@ -136,6 +139,12 @@ export function loadConfig(configPath = DEFAULT_CONFIG_PATH): MemoryConfig {
136
139
  if (typeof parsed.failureInjectionMaxAgeDays === "number") config.failureInjectionMaxAgeDays = parsed.failureInjectionMaxAgeDays;
137
140
  if (typeof parsed.failureInjectionMaxEntries === "number") config.failureInjectionMaxEntries = parsed.failureInjectionMaxEntries;
138
141
  if (typeof parsed.nudgeToolCalls === "number") config.nudgeToolCalls = parsed.nudgeToolCalls;
142
+ // Accept any finite number >= 0 so a user can both opt in (positive value)
143
+ // and explicitly disable retention with 0. Invalid/negative values are
144
+ // ignored, keeping the current (default) semantics.
145
+ if (typeof parsed.sessionRetentionDays === "number" && Number.isFinite(parsed.sessionRetentionDays) && parsed.sessionRetentionDays >= 0) {
146
+ config.sessionRetentionDays = parsed.sessionRetentionDays;
147
+ }
139
148
  if (typeof parsed.standingInstructionsEnabled === "boolean") config.standingInstructionsEnabled = parsed.standingInstructionsEnabled;
140
149
  if (typeof parsed.projectCharLimit === "number") config.projectCharLimit = parsed.projectCharLimit;
141
150
  if (typeof parsed.memoryDir === "string") {
@@ -153,10 +162,33 @@ export function loadConfig(configPath = DEFAULT_CONFIG_PATH): MemoryConfig {
153
162
  ) {
154
163
  config.sessionSearch = { variant: parsed.sessionSearch.variant };
155
164
  }
165
+ if (typeof parsed.quickCheckOnOpen === "boolean") config.quickCheckOnOpen = parsed.quickCheckOnOpen;
156
166
  if (typeof parsed.llmModelOverride === "string") {
157
167
  const trimmed = parsed.llmModelOverride.trim();
158
168
  if (trimmed.length > 0) config.llmModelOverride = trimmed;
159
169
  }
170
+ // Support array form for primary override too (e.g. llmModelOverride: ["a/b","c/d"]) — first entry is primary, rest are fallbacks
171
+ if (Array.isArray(parsed.llmModelOverride) && parsed.llmModelOverride.every((v: unknown) => typeof v === "string")) {
172
+ const cleaned = (parsed.llmModelOverride as string[]).map((s) => s.trim()).filter(Boolean);
173
+ if (cleaned.length > 0) {
174
+ config.llmModelOverride = cleaned[0];
175
+ const fallbacks = cleaned.slice(1);
176
+ if (fallbacks.length > 0) config.llmFallbackModels = fallbacks;
177
+ }
178
+ }
179
+ if (isStringArray(parsed.llmFallbackModels)) {
180
+ const cleaned = (parsed.llmFallbackModels as string[]).map((s) => s.trim()).filter(Boolean);
181
+ if (cleaned.length > 0) config.llmFallbackModels = [...new Set([...(config.llmFallbackModels ?? []), ...cleaned])];
182
+ }
183
+ // Backward-compat alias: llmModelFallbacks / fallbackModels
184
+ if (isStringArray((parsed as Record<string, unknown>).llmModelFallbacks)) {
185
+ const cleaned = ((parsed as Record<string, unknown>).llmModelFallbacks as string[]).map((s: string) => s.trim()).filter(Boolean);
186
+ if (cleaned.length > 0) config.llmFallbackModels = [...new Set([...(config.llmFallbackModels ?? []), ...cleaned])];
187
+ }
188
+ if (isStringArray((parsed as Record<string, unknown>).fallbackModels)) {
189
+ const cleaned = ((parsed as Record<string, unknown>).fallbackModels as string[]).map((s: string) => s.trim()).filter(Boolean);
190
+ if (cleaned.length > 0) config.llmFallbackModels = [...new Set([...(config.llmFallbackModels ?? []), ...cleaned])];
191
+ }
160
192
  if (isThinkingLevel(parsed.llmThinkingOverride)) config.llmThinkingOverride = parsed.llmThinkingOverride;
161
193
  if (isStringArray(parsed.childExtensionPaths)) {
162
194
  const childExtensionPaths = [...new Set<string>(
@@ -40,6 +40,16 @@ export const DEFAULT_OVERFLOW_GRACE_MS = 180000;
40
40
  export const DEFAULT_FAILURE_INJECTION_MAX_AGE_DAYS = 7;
41
41
  export const DEFAULT_FAILURE_INJECTION_MAX_ENTRIES = 5;
42
42
 
43
+ // ─── Session retention defaults ───
44
+ /**
45
+ * Default session retention window in days. `0` means retention pruning is
46
+ * DISABLED by default -- existing searchable session history is never silently
47
+ * deleted. Users opt in by setting `sessionRetentionDays` to a positive value
48
+ * in their config; setting it back to `0` (or omitting it) disables pruning
49
+ * (see #183).
50
+ */
51
+ export const DEFAULT_SESSION_RETENTION_DAYS = 0;
52
+
43
53
  // ─── File names ───
44
54
  export const MEMORY_FILE = "MEMORY.md";
45
55
  export const USER_FILE = "USER.md";
@@ -66,7 +76,7 @@ Memory write targets:
66
76
  - failure: failures, corrections, insights, conventions, preferences, and tool quirks captured as categorized lessons.
67
77
 
68
78
  memory_search filters:
69
- - target accepts "memory", "user", or "failure".
79
+ - target accepts "memory", "user", "failure", or "project" (project-attributed memory entries).
70
80
  - project filters project-scoped memories by project name.
71
81
  - category filters categorized failure/lesson memories only.
72
82
 
@@ -80,7 +90,7 @@ Accepted memory categories:
80
90
 
81
91
  Search guidance:
82
92
  - For user preferences, search target="user" with concrete terms from the request.
83
- - For project conventions or repo decisions, search with the current project filter and concrete terms from the request.
93
+ - For project conventions or repo decisions, search with the current project filter and concrete terms from the request; when the project name is unknown, search target="project" to match project-attributed memories regardless of name.
84
94
  - For debugging, test failures, build errors, or repeated mistakes, search target="failure" and categories "failure", "correction", "insight", or "tool-quirk".
85
95
  - For general durable learnings, search target="memory" with concrete terms from the request.
86
96
  - Use category only for categorized failure/lesson searches; ordinary user, global, and project memories may not have a category.
@@ -31,9 +31,11 @@ export interface BackgroundReviewDeps {
31
31
  runDirectReview?: typeof runDirectMemoryCompletion;
32
32
  execChildPrompt?: typeof execChildPrompt;
33
33
  /** Test-only hook: called once runReview() has fully settled (after the
34
- * fire-and-forget review work completes and reviewInProgress resets),
34
+ * fire-and-forget review work completes and activeReview clears),
35
35
  * since production callers never await runReview() directly. */
36
36
  onReviewSettled?: () => void;
37
+ /** Test-only override for session_shutdown's wait bound. */
38
+ shutdownGraceMs?: number;
37
39
  }
38
40
 
39
41
  export interface ReviewPromptInput {
@@ -113,17 +115,40 @@ function diagnosticDetail(value: unknown): string {
113
115
  return detail.replace(/\s+/g, " ").slice(0, 300);
114
116
  }
115
117
 
118
+ /** Shutdown wait only. Review still uses its own 120s timeout; 1s covers abort
119
+ * listener + cancel-file write without hanging Pi's awaited session_shutdown. */
120
+ const SESSION_REVIEW_SHUTDOWN_GRACE_MS = 1000;
121
+
122
+ function awaitUpTo(promise: Promise<void>, ms: number): Promise<void> {
123
+ return new Promise((resolve) => {
124
+ const timer = setTimeout(resolve, ms);
125
+ promise.then(
126
+ () => {
127
+ clearTimeout(timer);
128
+ resolve();
129
+ },
130
+ () => {
131
+ clearTimeout(timer);
132
+ resolve();
133
+ },
134
+ );
135
+ });
136
+ }
137
+
116
138
  async function runSubprocessReview(
117
139
  pi: ExtensionAPI,
118
140
  prompt: string,
119
141
  config: MemoryConfig,
120
142
  execChild: typeof execChildPrompt,
121
- ctx: Pick<ExtensionContext, "cwd" | "model" | "signal">,
143
+ ctx: Pick<ExtensionContext, "cwd" | "model">,
144
+ signal: AbortSignal,
122
145
  ): Promise<{ code: number; stdout?: string; stderr?: string }> {
123
146
  return execChild(pi, prompt, config, {
124
147
  cwd: ctx.cwd,
125
148
  model: resolveChildPiModel(ctx.model),
126
- signal: ctx.signal,
149
+ // Session-scoped signal only. The turn signal belongs to the interactive
150
+ // agent run; forwarding it cancels unrelated review on a later user abort.
151
+ signal,
127
152
  timeoutMs: 120000,
128
153
  });
129
154
  }
@@ -140,11 +165,27 @@ export function setupBackgroundReview(
140
165
  const runDirectReview = options.deps?.runDirectReview ?? runDirectMemoryCompletion;
141
166
  const execChild = options.deps?.execChildPrompt ?? execChildPrompt;
142
167
  const onReviewSettled = options.deps?.onReviewSettled;
168
+ const shutdownGraceMs = options.deps?.shutdownGraceMs ?? SESSION_REVIEW_SHUTDOWN_GRACE_MS;
143
169
 
144
170
  let turnsSinceReview = 0;
145
171
  let toolCallsSinceReview = 0;
146
172
  let userTurnCount = 0;
147
- let reviewInProgress = false;
173
+ let activeReview: Promise<void> | undefined;
174
+ const sessionAbort = new AbortController();
175
+ let shutdownPromise: Promise<void> | undefined;
176
+
177
+ const sessionCancelled = () => sessionAbort.signal.aborted;
178
+
179
+ const shutdownReview = (): Promise<void> => {
180
+ shutdownPromise ??= (async () => {
181
+ sessionAbort.abort();
182
+ const inFlight = activeReview;
183
+ if (inFlight) await awaitUpTo(inFlight, shutdownGraceMs);
184
+ })();
185
+ return shutdownPromise;
186
+ };
187
+
188
+ pi.on("session_shutdown", () => shutdownReview());
148
189
 
149
190
  pi.on("message_end", async (event, _ctx) => {
150
191
  if (event.message.role === "user") {
@@ -156,7 +197,8 @@ export function setupBackgroundReview(
156
197
  turnsSinceReview++;
157
198
 
158
199
  if (!config.reviewEnabled) return;
159
- if (reviewInProgress) return;
200
+ if (sessionCancelled()) return;
201
+ if (activeReview) return;
160
202
 
161
203
  try {
162
204
  const msg = event.message;
@@ -179,49 +221,52 @@ export function setupBackgroundReview(
179
221
 
180
222
  if (!turnThresholdMet && !toolCallThresholdMet) return;
181
223
  if (userTurnCount < 3) return;
224
+ if (sessionCancelled()) return;
182
225
 
183
226
  turnsSinceReview = 0;
184
227
  toolCallsSinceReview = 0;
185
- reviewInProgress = true;
186
-
187
- let allParts: string[] = [];
188
- try {
189
- const entries = ctx.sessionManager.getBranch();
190
- allParts = collectMessageParts(entries);
191
- } catch {
192
- reviewInProgress = false;
193
- return;
194
- }
195
- if (allParts.length < 4) {
196
- reviewInProgress = false;
197
- return;
198
- }
199
-
200
- const parts = applyRecentMessageLimit(allParts, config.reviewRecentMessages);
201
- const activeProjectStore = resolveProjectStore(projectStore);
202
- const activeProjectName = resolveProjectName(projectName);
203
- const promptInput: ReviewPromptInput = {
204
- parts,
205
- currentMemory: store.getMemoryEntries().join("\n§\n"),
206
- currentUser: store.getUserEntries().join("\n§\n"),
207
- currentProject: activeProjectStore ? activeProjectStore.getMemoryEntries().join("\n§\n") : null,
208
- };
209
-
210
- const subprocessPrompt = buildSubprocessReviewPrompt(promptInput);
211
- const directPrompt = buildDirectReviewUserPrompt(promptInput);
212
-
213
- const finishReview = () => {
214
- reviewInProgress = false;
215
- onReviewSettled?.();
216
- };
217
228
 
218
229
  const notifyIfSaved = (saved: boolean) => {
230
+ if (sessionCancelled()) return;
219
231
  if (saved) {
220
232
  ctx.ui.notify("💾 Memory auto-reviewed and updated", "info");
221
233
  }
222
234
  };
223
235
 
236
+ const notifyTransportFailure = (directFailure: string, subprocessDetail: unknown) => {
237
+ if (sessionCancelled()) return;
238
+ ctx.ui.notify(
239
+ `Memory auto-review failed in both transports. Direct: ${diagnosticDetail(directFailure)}. `
240
+ + `Subprocess: ${diagnosticDetail(subprocessDetail)}. Check the active model/provider or set llmModelOverride.`,
241
+ "warning",
242
+ );
243
+ };
244
+
224
245
  const runReview = async (): Promise<void> => {
246
+ if (sessionCancelled()) return;
247
+
248
+ let allParts: string[] = [];
249
+ try {
250
+ const entries = ctx.sessionManager.getBranch();
251
+ allParts = collectMessageParts(entries);
252
+ } catch {
253
+ return;
254
+ }
255
+ if (allParts.length < 4) return;
256
+ if (sessionCancelled()) return;
257
+
258
+ const parts = applyRecentMessageLimit(allParts, config.reviewRecentMessages);
259
+ const activeProjectStore = resolveProjectStore(projectStore);
260
+ const activeProjectName = resolveProjectName(projectName);
261
+ const promptInput: ReviewPromptInput = {
262
+ parts,
263
+ currentMemory: store.getMemoryEntries().join("\n§\n"),
264
+ currentUser: store.getUserEntries().join("\n§\n"),
265
+ currentProject: activeProjectStore ? activeProjectStore.getMemoryEntries().join("\n§\n") : null,
266
+ };
267
+ const subprocessPrompt = buildSubprocessReviewPrompt(promptInput);
268
+ const directPrompt = buildDirectReviewUserPrompt(promptInput);
269
+
225
270
  let directFailure: string | undefined;
226
271
 
227
272
  if (usesDirectTransport(config)) {
@@ -239,17 +284,20 @@ export function setupBackgroundReview(
239
284
  ].join("\n"),
240
285
  config,
241
286
  timeoutMs: 120000,
287
+ signal: sessionAbort.signal,
242
288
  },
243
289
  dbManager,
244
290
  activeProjectName,
245
291
  );
246
292
 
293
+ if (sessionCancelled()) return;
294
+
247
295
  if (directResult.ok) {
248
296
  notifyIfSaved(shouldNotifyDirect(directResult));
249
297
  return;
250
298
  }
251
299
 
252
- if (directResult.fallbackReason === "empty") {
300
+ if (directResult.fallbackReason === "empty" || directResult.fallbackReason === "aborted") {
253
301
  return;
254
302
  }
255
303
  directFailure = [
@@ -257,41 +305,51 @@ export function setupBackgroundReview(
257
305
  directResult.error,
258
306
  ].filter(Boolean).join(": ");
259
307
  } catch (error) {
308
+ if (sessionCancelled()) return;
260
309
  directFailure = diagnosticDetail(error);
261
310
  }
262
311
  }
263
312
 
313
+ if (sessionCancelled()) return;
314
+
264
315
  let subprocessResult: { code: number; stdout?: string; stderr?: string };
265
316
  try {
266
- subprocessResult = await runSubprocessReview(pi, subprocessPrompt, config, execChild, ctx);
317
+ subprocessResult = await runSubprocessReview(
318
+ pi,
319
+ subprocessPrompt,
320
+ config,
321
+ execChild,
322
+ ctx,
323
+ sessionAbort.signal,
324
+ );
267
325
  } catch (error) {
268
326
  if (directFailure) {
269
- ctx.ui.notify(
270
- `Memory auto-review failed in both transports. Direct: ${diagnosticDetail(directFailure)}. `
271
- + `Subprocess: ${diagnosticDetail(error)}. Check the active model/provider or set llmModelOverride.`,
272
- "warning",
273
- );
327
+ notifyTransportFailure(directFailure, error);
274
328
  }
275
329
  return;
276
330
  }
277
331
 
332
+ if (sessionCancelled()) return;
333
+
278
334
  if (subprocessResult.code === 0) {
279
335
  notifyIfSaved(shouldNotifySubprocess(subprocessResult.stdout));
280
336
  } else if (directFailure) {
281
337
  const subprocessDetail = subprocessResult.stderr?.trim() || subprocessResult.stdout?.trim()
282
338
  || `exit code ${subprocessResult.code}`;
283
- ctx.ui.notify(
284
- `Memory auto-review failed in both transports. Direct: ${diagnosticDetail(directFailure)}. `
285
- + `Subprocess: ${diagnosticDetail(subprocessDetail)}. Check the active model/provider or set llmModelOverride.`,
286
- "warning",
287
- );
339
+ notifyTransportFailure(directFailure, subprocessDetail);
288
340
  }
289
341
  };
290
342
 
291
- runReview()
343
+ // Occupy the in-flight slot before runReview's synchronous preamble so a
344
+ // nested turn_end cannot start a second review.
345
+ activeReview = Promise.resolve()
346
+ .then(() => runReview())
292
347
  .catch(() => {
293
348
  // Best-effort only; transport failures are diagnosed after both paths settle.
294
349
  })
295
- .finally(finishReview);
350
+ .finally(() => {
351
+ activeReview = undefined;
352
+ onReviewSettled?.();
353
+ });
296
354
  });
297
355
  }
@@ -6,13 +6,14 @@ import path from 'node:path';
6
6
  import fs from 'node:fs';
7
7
  import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
8
8
  import { DatabaseManager } from '../store/db.js';
9
- import { indexAllSessions, getSessionStats } from '../store/session-indexer.js';
9
+ import { indexAllSessions, getSessionStats, retentionCutoffMs } from '../store/session-indexer.js';
10
+ import type { MemoryConfig } from '../types.js';
10
11
  import { AGENT_ROOT } from '../paths.js';
11
12
 
12
13
  const SESSIONS_DIR = process.env.SELESAI_CODING_AGENT_SESSION_DIR
13
14
  || path.join(AGENT_ROOT, 'sessions');
14
15
 
15
- export function registerIndexSessionsCommand(pi: ExtensionAPI): void {
16
+ export function registerIndexSessionsCommand(pi: ExtensionAPI, config: MemoryConfig): void {
16
17
  pi.registerCommand("memory-index-sessions", {
17
18
  description: "Import past Pi sessions into the search database",
18
19
  handler: async (_args, ctx: ExtensionCommandContext) => {
@@ -39,7 +40,9 @@ export function registerIndexSessionsCommand(pi: ExtensionAPI): void {
39
40
  const dbManager = new DatabaseManager(memoryDir);
40
41
 
41
42
  try {
42
- const result = indexAllSessions(dbManager, SESSIONS_DIR);
43
+ // Retention is honored here too: a manual reindex must not re-add the
44
+ // expired sessions the auto pruning just deleted.
45
+ const result = indexAllSessions(dbManager, SESSIONS_DIR, undefined, retentionCutoffMs(config.sessionRetentionDays));
43
46
  const stats = getSessionStats(dbManager);
44
47
 
45
48
  let output = `\n✅ Session indexing complete!\n\n`;
@@ -47,6 +50,9 @@ export function registerIndexSessionsCommand(pi: ExtensionAPI): void {
47
50
  output += `├─ Sessions processed: ${result.sessionsProcessed}\n`;
48
51
  output += `├─ Sessions indexed: ${result.sessionsIndexed}\n`;
49
52
  output += `├─ Sessions skipped (already indexed): ${result.sessionsSkipped}\n`;
53
+ if (result.expiredSkipped) {
54
+ output += `├─ Sessions skipped (outside retention): ${result.expiredSkipped}\n`;
55
+ }
50
56
  output += `└─ Messages indexed: ${result.messagesIndexed}\n`;
51
57
 
52
58
  if (stats.projects.length > 0) {