pi-usereq 0.49.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (938) hide show
  1. package/README.md +1 -1
  2. package/package.json +5 -1
  3. package/scripts/lib/extension-debug-harness.ts +443 -0
  4. package/scripts/lib/recording-extension-api.ts +855 -0
  5. package/scripts/lib/sdk-smoke.ts +503 -0
  6. package/.g.conf +0 -16
  7. package/.github/workflows/release-npm.yml +0 -134
  8. package/.gitignore +0 -274
  9. package/CHANGELOG.md +0 -706
  10. package/TODO.md +0 -20
  11. package/docs/pi.dev/agent-document-manifest.json +0 -6399
  12. package/docs/pi.dev/coding-agent-docs/compaction.md +0 -394
  13. package/docs/pi.dev/coding-agent-docs/custom-provider.md +0 -637
  14. package/docs/pi.dev/coding-agent-docs/development.md +0 -71
  15. package/docs/pi.dev/coding-agent-docs/extensions.md +0 -2536
  16. package/docs/pi.dev/coding-agent-docs/images/doom-extension.png +0 -0
  17. package/docs/pi.dev/coding-agent-docs/images/exy.png +0 -0
  18. package/docs/pi.dev/coding-agent-docs/images/interactive-mode.png +0 -0
  19. package/docs/pi.dev/coding-agent-docs/images/tree-view.png +0 -0
  20. package/docs/pi.dev/coding-agent-docs/json.md +0 -82
  21. package/docs/pi.dev/coding-agent-docs/keybindings.md +0 -197
  22. package/docs/pi.dev/coding-agent-docs/models.md +0 -395
  23. package/docs/pi.dev/coding-agent-docs/packages.md +0 -218
  24. package/docs/pi.dev/coding-agent-docs/prompt-templates.md +0 -88
  25. package/docs/pi.dev/coding-agent-docs/providers.md +0 -196
  26. package/docs/pi.dev/coding-agent-docs/rpc.md +0 -1407
  27. package/docs/pi.dev/coding-agent-docs/sdk.md +0 -1149
  28. package/docs/pi.dev/coding-agent-docs/session.md +0 -412
  29. package/docs/pi.dev/coding-agent-docs/settings.md +0 -248
  30. package/docs/pi.dev/coding-agent-docs/shell-aliases.md +0 -13
  31. package/docs/pi.dev/coding-agent-docs/skills.md +0 -232
  32. package/docs/pi.dev/coding-agent-docs/terminal-setup.md +0 -106
  33. package/docs/pi.dev/coding-agent-docs/termux.md +0 -127
  34. package/docs/pi.dev/coding-agent-docs/themes.md +0 -295
  35. package/docs/pi.dev/coding-agent-docs/tmux.md +0 -61
  36. package/docs/pi.dev/coding-agent-docs/tree.md +0 -233
  37. package/docs/pi.dev/coding-agent-docs/tui.md +0 -918
  38. package/docs/pi.dev/coding-agent-docs/windows.md +0 -17
  39. package/docs/pi.dev/mom-docs/artifacts-server.md +0 -475
  40. package/docs/pi.dev/mom-docs/events.md +0 -307
  41. package/docs/pi.dev/mom-docs/new.md +0 -970
  42. package/docs/pi.dev/mom-docs/sandbox.md +0 -153
  43. package/docs/pi.dev/mom-docs/slack-bot-minimal-guide.md +0 -399
  44. package/docs/pi.dev/mom-docs/v86.md +0 -319
  45. package/docs/pi.dev/pods-docs/gml-4.5.md +0 -189
  46. package/docs/pi.dev/pods-docs/gpt-oss.md +0 -233
  47. package/docs/pi.dev/pods-docs/implementation-plan.md +0 -183
  48. package/docs/pi.dev/pods-docs/kimi-k2.md +0 -197
  49. package/docs/pi.dev/pods-docs/models.md +0 -116
  50. package/docs/pi.dev/pods-docs/plan.md +0 -166
  51. package/docs/pi.dev/pods-docs/qwen3-coder.md +0 -132
  52. package/images/flowchart-bw.png +0 -0
  53. package/images/flowchart-bw.svg +0 -102
  54. package/images/flowchart.md +0 -100
  55. package/images/flowchart.png +0 -0
  56. package/images/flowchart.svg +0 -3
  57. package/pi-usereq/docs/REFERENCES.md +0 -5713
  58. package/pi-usereq/docs/REQUIREMENTS.md +0 -781
  59. package/pi-usereq/docs/WORKFLOW.md +0 -1341
  60. package/pi.dev-src/pi-mono/agent/src/agent-loop.ts +0 -683
  61. package/pi.dev-src/pi-mono/agent/src/agent.ts +0 -543
  62. package/pi.dev-src/pi-mono/agent/src/index.ts +0 -8
  63. package/pi.dev-src/pi-mono/agent/src/proxy.ts +0 -367
  64. package/pi.dev-src/pi-mono/agent/src/types.ts +0 -364
  65. package/pi.dev-src/pi-mono/agent/test/agent-loop.test.ts +0 -1181
  66. package/pi.dev-src/pi-mono/agent/test/agent.test.ts +0 -463
  67. package/pi.dev-src/pi-mono/agent/test/e2e.test.ts +0 -404
  68. package/pi.dev-src/pi-mono/agent/test/utils/calculate.ts +0 -32
  69. package/pi.dev-src/pi-mono/agent/test/utils/get-current-time.ts +0 -46
  70. package/pi.dev-src/pi-mono/agent/vitest.config.ts +0 -9
  71. package/pi.dev-src/pi-mono/ai/bedrock-provider.d.ts +0 -1
  72. package/pi.dev-src/pi-mono/ai/bedrock-provider.js +0 -1
  73. package/pi.dev-src/pi-mono/ai/scripts/generate-models.ts +0 -1635
  74. package/pi.dev-src/pi-mono/ai/scripts/generate-test-image.ts +0 -34
  75. package/pi.dev-src/pi-mono/ai/src/api-registry.ts +0 -98
  76. package/pi.dev-src/pi-mono/ai/src/bedrock-provider.ts +0 -6
  77. package/pi.dev-src/pi-mono/ai/src/cli.ts +0 -133
  78. package/pi.dev-src/pi-mono/ai/src/env-api-keys.ts +0 -134
  79. package/pi.dev-src/pi-mono/ai/src/index.ts +0 -35
  80. package/pi.dev-src/pi-mono/ai/src/models.generated.ts +0 -14928
  81. package/pi.dev-src/pi-mono/ai/src/models.ts +0 -82
  82. package/pi.dev-src/pi-mono/ai/src/oauth.ts +0 -1
  83. package/pi.dev-src/pi-mono/ai/src/providers/amazon-bedrock.ts +0 -929
  84. package/pi.dev-src/pi-mono/ai/src/providers/anthropic.ts +0 -1125
  85. package/pi.dev-src/pi-mono/ai/src/providers/azure-openai-responses.ts +0 -253
  86. package/pi.dev-src/pi-mono/ai/src/providers/faux.ts +0 -499
  87. package/pi.dev-src/pi-mono/ai/src/providers/github-copilot-headers.ts +0 -37
  88. package/pi.dev-src/pi-mono/ai/src/providers/google-gemini-cli.ts +0 -996
  89. package/pi.dev-src/pi-mono/ai/src/providers/google-shared.ts +0 -354
  90. package/pi.dev-src/pi-mono/ai/src/providers/google-vertex.ts +0 -543
  91. package/pi.dev-src/pi-mono/ai/src/providers/google.ts +0 -500
  92. package/pi.dev-src/pi-mono/ai/src/providers/mistral.ts +0 -629
  93. package/pi.dev-src/pi-mono/ai/src/providers/openai-codex-responses.ts +0 -984
  94. package/pi.dev-src/pi-mono/ai/src/providers/openai-completions.ts +0 -1063
  95. package/pi.dev-src/pi-mono/ai/src/providers/openai-responses-shared.ts +0 -539
  96. package/pi.dev-src/pi-mono/ai/src/providers/openai-responses.ts +0 -264
  97. package/pi.dev-src/pi-mono/ai/src/providers/register-builtins.ts +0 -433
  98. package/pi.dev-src/pi-mono/ai/src/providers/simple-options.ts +0 -47
  99. package/pi.dev-src/pi-mono/ai/src/providers/transform-messages.ts +0 -220
  100. package/pi.dev-src/pi-mono/ai/src/stream.ts +0 -59
  101. package/pi.dev-src/pi-mono/ai/src/types.ts +0 -417
  102. package/pi.dev-src/pi-mono/ai/src/utils/event-stream.ts +0 -87
  103. package/pi.dev-src/pi-mono/ai/src/utils/hash.ts +0 -13
  104. package/pi.dev-src/pi-mono/ai/src/utils/headers.ts +0 -7
  105. package/pi.dev-src/pi-mono/ai/src/utils/json-parse.ts +0 -124
  106. package/pi.dev-src/pi-mono/ai/src/utils/overflow.ts +0 -138
  107. package/pi.dev-src/pi-mono/ai/src/utils/sanitize-unicode.ts +0 -25
  108. package/pi.dev-src/pi-mono/ai/src/utils/typebox-helpers.ts +0 -24
  109. package/pi.dev-src/pi-mono/ai/src/utils/validation.ts +0 -324
  110. package/pi.dev-src/pi-mono/ai/test/abort.test.ts +0 -260
  111. package/pi.dev-src/pi-mono/ai/test/anthropic-oauth.test.ts +0 -99
  112. package/pi.dev-src/pi-mono/ai/test/anthropic-opus-4-7-smoke.test.ts +0 -72
  113. package/pi.dev-src/pi-mono/ai/test/anthropic-sse-parsing.test.ts +0 -113
  114. package/pi.dev-src/pi-mono/ai/test/anthropic-thinking-disable.test.ts +0 -152
  115. package/pi.dev-src/pi-mono/ai/test/anthropic-tool-name-normalization.test.ts +0 -205
  116. package/pi.dev-src/pi-mono/ai/test/azure-utils.ts +0 -28
  117. package/pi.dev-src/pi-mono/ai/test/bedrock-endpoint-resolution.test.ts +0 -131
  118. package/pi.dev-src/pi-mono/ai/test/bedrock-models.test.ts +0 -66
  119. package/pi.dev-src/pi-mono/ai/test/bedrock-thinking-payload.test.ts +0 -107
  120. package/pi.dev-src/pi-mono/ai/test/bedrock-utils.ts +0 -18
  121. package/pi.dev-src/pi-mono/ai/test/cache-retention.test.ts +0 -335
  122. package/pi.dev-src/pi-mono/ai/test/context-overflow.test.ts +0 -714
  123. package/pi.dev-src/pi-mono/ai/test/cross-provider-handoff.test.ts +0 -458
  124. package/pi.dev-src/pi-mono/ai/test/data/red-circle.png +0 -0
  125. package/pi.dev-src/pi-mono/ai/test/empty.test.ts +0 -742
  126. package/pi.dev-src/pi-mono/ai/test/faux-provider.test.ts +0 -597
  127. package/pi.dev-src/pi-mono/ai/test/fireworks-models.test.ts +0 -49
  128. package/pi.dev-src/pi-mono/ai/test/github-copilot-anthropic.test.ts +0 -108
  129. package/pi.dev-src/pi-mono/ai/test/github-copilot-oauth.test.ts +0 -196
  130. package/pi.dev-src/pi-mono/ai/test/google-gemini-cli-claude-thinking-header.test.ts +0 -103
  131. package/pi.dev-src/pi-mono/ai/test/google-gemini-cli-empty-stream.test.ts +0 -108
  132. package/pi.dev-src/pi-mono/ai/test/google-gemini-cli-retry-delay.test.ts +0 -53
  133. package/pi.dev-src/pi-mono/ai/test/google-shared-convert-tools.test.ts +0 -187
  134. package/pi.dev-src/pi-mono/ai/test/google-shared-gemini3-unsigned-tool-call.test.ts +0 -172
  135. package/pi.dev-src/pi-mono/ai/test/google-shared-image-tool-result-routing.test.ts +0 -124
  136. package/pi.dev-src/pi-mono/ai/test/google-thinking-disable.test.ts +0 -183
  137. package/pi.dev-src/pi-mono/ai/test/google-thinking-signature.test.ts +0 -38
  138. package/pi.dev-src/pi-mono/ai/test/google-tool-call-missing-args.test.ts +0 -105
  139. package/pi.dev-src/pi-mono/ai/test/google-vertex-api-key-resolution.test.ts +0 -144
  140. package/pi.dev-src/pi-mono/ai/test/image-tool-result.test.ts +0 -481
  141. package/pi.dev-src/pi-mono/ai/test/interleaved-thinking.test.ts +0 -145
  142. package/pi.dev-src/pi-mono/ai/test/lazy-module-load.test.ts +0 -102
  143. package/pi.dev-src/pi-mono/ai/test/mistral-reasoning-mode.test.ts +0 -66
  144. package/pi.dev-src/pi-mono/ai/test/mistral-tool-schema.test.ts +0 -61
  145. package/pi.dev-src/pi-mono/ai/test/oauth.ts +0 -89
  146. package/pi.dev-src/pi-mono/ai/test/openai-codex-cache-affinity-e2e.test.ts +0 -36
  147. package/pi.dev-src/pi-mono/ai/test/openai-codex-stream.test.ts +0 -686
  148. package/pi.dev-src/pi-mono/ai/test/openai-completions-cache-control-format.test.ts +0 -189
  149. package/pi.dev-src/pi-mono/ai/test/openai-completions-prompt-cache.test.ts +0 -198
  150. package/pi.dev-src/pi-mono/ai/test/openai-completions-thinking-as-text.test.ts +0 -214
  151. package/pi.dev-src/pi-mono/ai/test/openai-completions-tool-choice.test.ts +0 -560
  152. package/pi.dev-src/pi-mono/ai/test/openai-completions-tool-result-images.test.ts +0 -101
  153. package/pi.dev-src/pi-mono/ai/test/openai-responses-cache-affinity-e2e.test.ts +0 -32
  154. package/pi.dev-src/pi-mono/ai/test/openai-responses-copilot-provider.test.ts +0 -128
  155. package/pi.dev-src/pi-mono/ai/test/openai-responses-foreign-toolcall-id.test.ts +0 -66
  156. package/pi.dev-src/pi-mono/ai/test/openai-responses-partial-json-cleanup.test.ts +0 -101
  157. package/pi.dev-src/pi-mono/ai/test/openai-responses-reasoning-replay-e2e.test.ts +0 -292
  158. package/pi.dev-src/pi-mono/ai/test/openai-responses-tool-result-images.test.ts +0 -200
  159. package/pi.dev-src/pi-mono/ai/test/openrouter-cache-write-repro.test.ts +0 -78
  160. package/pi.dev-src/pi-mono/ai/test/overflow.test.ts +0 -64
  161. package/pi.dev-src/pi-mono/ai/test/responseid.test.ts +0 -145
  162. package/pi.dev-src/pi-mono/ai/test/stream.test.ts +0 -1405
  163. package/pi.dev-src/pi-mono/ai/test/supports-xhigh.test.ts +0 -34
  164. package/pi.dev-src/pi-mono/ai/test/tokens.test.ts +0 -304
  165. package/pi.dev-src/pi-mono/ai/test/tool-call-id-normalization.test.ts +0 -291
  166. package/pi.dev-src/pi-mono/ai/test/tool-call-without-result.test.ts +0 -313
  167. package/pi.dev-src/pi-mono/ai/test/total-tokens.test.ts +0 -695
  168. package/pi.dev-src/pi-mono/ai/test/transform-messages-copilot-openai-to-anthropic.test.ts +0 -191
  169. package/pi.dev-src/pi-mono/ai/test/unicode-surrogate.test.ts +0 -754
  170. package/pi.dev-src/pi-mono/ai/test/validation.test.ts +0 -116
  171. package/pi.dev-src/pi-mono/ai/test/xhigh.test.ts +0 -71
  172. package/pi.dev-src/pi-mono/ai/test/zen.test.ts +0 -25
  173. package/pi.dev-src/pi-mono/ai/vitest.config.ts +0 -9
  174. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/antigravity-image-gen.ts +0 -418
  175. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/auto-commit-on-exit.ts +0 -49
  176. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/bash-spawn-hook.ts +0 -30
  177. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/bookmark.ts +0 -50
  178. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/built-in-tool-renderer.ts +0 -249
  179. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/claude-rules.ts +0 -86
  180. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/commands.ts +0 -72
  181. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/confirm-destructive.ts +0 -59
  182. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-compaction.ts +0 -127
  183. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-footer.ts +0 -64
  184. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-header.ts +0 -73
  185. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-anthropic/index.ts +0 -604
  186. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-anthropic/package-lock.json +0 -24
  187. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-gitlab-duo/index.ts +0 -349
  188. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-gitlab-duo/test.ts +0 -82
  189. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-qwen-cli/index.ts +0 -345
  190. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dirty-repo-guard.ts +0 -56
  191. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom/build.sh +0 -152
  192. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +0 -72
  193. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom-component.ts +0 -132
  194. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom-engine.ts +0 -173
  195. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom-keys.ts +0 -104
  196. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/index.ts +0 -74
  197. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/wad-finder.ts +0 -51
  198. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/SKILL.md +0 -8
  199. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/dynamic.json +0 -79
  200. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/dynamic.md +0 -5
  201. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/index.ts +0 -15
  202. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-tools.ts +0 -74
  203. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/event-bus.ts +0 -43
  204. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/file-trigger.ts +0 -41
  205. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/git-checkpoint.ts +0 -53
  206. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/github-issue-autocomplete.ts +0 -185
  207. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/handoff.ts +0 -153
  208. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/hello.ts +0 -26
  209. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/hidden-thinking-label.ts +0 -53
  210. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/inline-bash.ts +0 -94
  211. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/input-transform.ts +0 -43
  212. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/interactive-shell.ts +0 -196
  213. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/mac-system-theme.ts +0 -47
  214. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/message-renderer.ts +0 -59
  215. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/minimal-mode.ts +0 -426
  216. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/modal-editor.ts +0 -85
  217. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/model-status.ts +0 -31
  218. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/notify.ts +0 -55
  219. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/overlay-qa-tests.ts +0 -1348
  220. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/overlay-test.ts +0 -150
  221. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/permission-gate.ts +0 -34
  222. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/pirate.ts +0 -47
  223. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/plan-mode/index.ts +0 -340
  224. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/plan-mode/utils.ts +0 -168
  225. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/preset.ts +0 -430
  226. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/prompt-customizer.ts +0 -97
  227. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/protected-paths.ts +0 -30
  228. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/provider-payload.ts +0 -18
  229. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/qna.ts +0 -122
  230. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/question.ts +0 -264
  231. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/questionnaire.ts +0 -427
  232. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/rainbow-editor.ts +0 -88
  233. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/reload-runtime.ts +0 -37
  234. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/rpc-demo.ts +0 -118
  235. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/sandbox/index.ts +0 -321
  236. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/sandbox/package-lock.json +0 -92
  237. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/send-user-message.ts +0 -97
  238. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/session-name.ts +0 -27
  239. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/shutdown-command.ts +0 -63
  240. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/snake.ts +0 -343
  241. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/space-invaders.ts +0 -560
  242. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/ssh.ts +0 -220
  243. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/status-line.ts +0 -32
  244. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/structured-output.ts +0 -65
  245. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/planner.md +0 -37
  246. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/reviewer.md +0 -35
  247. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/scout.md +0 -50
  248. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/worker.md +0 -24
  249. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents.ts +0 -126
  250. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/index.ts +0 -987
  251. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  252. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/prompts/implement.md +0 -10
  253. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
  254. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/summarize.ts +0 -206
  255. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/system-prompt-header.ts +0 -17
  256. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/tic-tac-toe.ts +0 -1008
  257. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/timed-confirm.ts +0 -70
  258. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/titlebar-spinner.ts +0 -58
  259. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/todo.ts +0 -297
  260. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/tool-override.ts +0 -144
  261. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/tools.ts +0 -141
  262. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/trigger-compact.ts +0 -50
  263. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/truncated-tool.ts +0 -195
  264. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/widget-placement.ts +0 -9
  265. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/with-deps/index.ts +0 -32
  266. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/with-deps/package-lock.json +0 -31
  267. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/working-indicator.ts +0 -123
  268. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/working-message-test.ts +0 -25
  269. package/pi.dev-src/pi-mono/coding-agent/examples/rpc-extension-ui.ts +0 -632
  270. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/01-minimal.ts +0 -22
  271. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/02-custom-model.ts +0 -49
  272. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/03-custom-prompt.ts +0 -62
  273. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/04-skills.ts +0 -55
  274. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/05-tools.ts +0 -44
  275. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/06-extensions.ts +0 -90
  276. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/07-context-files.ts +0 -42
  277. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/08-prompt-templates.ts +0 -51
  278. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/09-api-keys-and-oauth.ts +0 -48
  279. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/10-settings.ts +0 -53
  280. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/11-sessions.ts +0 -48
  281. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/12-full-control.ts +0 -73
  282. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/13-session-runtime.ts +0 -67
  283. package/pi.dev-src/pi-mono/coding-agent/scripts/migrate-sessions.sh +0 -93
  284. package/pi.dev-src/pi-mono/coding-agent/src/bun/cli.ts +0 -6
  285. package/pi.dev-src/pi-mono/coding-agent/src/bun/register-bedrock.ts +0 -4
  286. package/pi.dev-src/pi-mono/coding-agent/src/cli/args.ts +0 -335
  287. package/pi.dev-src/pi-mono/coding-agent/src/cli/config-selector.ts +0 -52
  288. package/pi.dev-src/pi-mono/coding-agent/src/cli/file-processor.ts +0 -100
  289. package/pi.dev-src/pi-mono/coding-agent/src/cli/initial-message.ts +0 -43
  290. package/pi.dev-src/pi-mono/coding-agent/src/cli/list-models.ts +0 -110
  291. package/pi.dev-src/pi-mono/coding-agent/src/cli/session-picker.ts +0 -52
  292. package/pi.dev-src/pi-mono/coding-agent/src/cli.ts +0 -17
  293. package/pi.dev-src/pi-mono/coding-agent/src/config.ts +0 -261
  294. package/pi.dev-src/pi-mono/coding-agent/src/core/agent-session-runtime.ts +0 -394
  295. package/pi.dev-src/pi-mono/coding-agent/src/core/agent-session-services.ts +0 -196
  296. package/pi.dev-src/pi-mono/coding-agent/src/core/agent-session.ts +0 -3096
  297. package/pi.dev-src/pi-mono/coding-agent/src/core/auth-storage.ts +0 -493
  298. package/pi.dev-src/pi-mono/coding-agent/src/core/bash-executor.ts +0 -154
  299. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/branch-summarization.ts +0 -355
  300. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/compaction.ts +0 -839
  301. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/index.ts +0 -7
  302. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/utils.ts +0 -170
  303. package/pi.dev-src/pi-mono/coding-agent/src/core/defaults.ts +0 -3
  304. package/pi.dev-src/pi-mono/coding-agent/src/core/diagnostics.ts +0 -15
  305. package/pi.dev-src/pi-mono/coding-agent/src/core/event-bus.ts +0 -33
  306. package/pi.dev-src/pi-mono/coding-agent/src/core/exec.ts +0 -107
  307. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/ansi-to-html.ts +0 -258
  308. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/index.ts +0 -314
  309. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/template.css +0 -1017
  310. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/template.html +0 -55
  311. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/template.js +0 -1770
  312. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/tool-renderer.ts +0 -158
  313. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/vendor/highlight.min.js +0 -1213
  314. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/vendor/marked.min.js +0 -6
  315. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/index.ts +0 -171
  316. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/loader.ts +0 -606
  317. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/runner.ts +0 -1019
  318. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/types.ts +0 -1542
  319. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/wrapper.ts +0 -30
  320. package/pi.dev-src/pi-mono/coding-agent/src/core/footer-data-provider.ts +0 -354
  321. package/pi.dev-src/pi-mono/coding-agent/src/core/index.ts +0 -77
  322. package/pi.dev-src/pi-mono/coding-agent/src/core/keybindings.ts +0 -370
  323. package/pi.dev-src/pi-mono/coding-agent/src/core/messages.ts +0 -195
  324. package/pi.dev-src/pi-mono/coding-agent/src/core/model-registry.ts +0 -858
  325. package/pi.dev-src/pi-mono/coding-agent/src/core/model-resolver.ts +0 -629
  326. package/pi.dev-src/pi-mono/coding-agent/src/core/output-guard.ts +0 -74
  327. package/pi.dev-src/pi-mono/coding-agent/src/core/package-manager.ts +0 -2408
  328. package/pi.dev-src/pi-mono/coding-agent/src/core/prompt-templates.ts +0 -296
  329. package/pi.dev-src/pi-mono/coding-agent/src/core/resolve-config-value.ts +0 -142
  330. package/pi.dev-src/pi-mono/coding-agent/src/core/resource-loader.ts +0 -917
  331. package/pi.dev-src/pi-mono/coding-agent/src/core/sdk.ts +0 -380
  332. package/pi.dev-src/pi-mono/coding-agent/src/core/session-cwd.ts +0 -59
  333. package/pi.dev-src/pi-mono/coding-agent/src/core/session-manager.ts +0 -1425
  334. package/pi.dev-src/pi-mono/coding-agent/src/core/settings-manager.ts +0 -999
  335. package/pi.dev-src/pi-mono/coding-agent/src/core/skills.ts +0 -508
  336. package/pi.dev-src/pi-mono/coding-agent/src/core/slash-commands.ts +0 -39
  337. package/pi.dev-src/pi-mono/coding-agent/src/core/source-info.ts +0 -40
  338. package/pi.dev-src/pi-mono/coding-agent/src/core/system-prompt.ts +0 -172
  339. package/pi.dev-src/pi-mono/coding-agent/src/core/telemetry.ts +0 -13
  340. package/pi.dev-src/pi-mono/coding-agent/src/core/timings.ts +0 -31
  341. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/bash.ts +0 -448
  342. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/edit-diff.ts +0 -445
  343. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/edit.ts +0 -487
  344. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/file-mutation-queue.ts +0 -39
  345. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/find.ts +0 -370
  346. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/grep.ts +0 -384
  347. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/index.ts +0 -196
  348. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/ls.ts +0 -229
  349. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/path-utils.ts +0 -94
  350. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/read.ts +0 -273
  351. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/render-utils.ts +0 -64
  352. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/tool-definition-wrapper.ts +0 -45
  353. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/truncate.ts +0 -265
  354. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/write.ts +0 -281
  355. package/pi.dev-src/pi-mono/coding-agent/src/index.ts +0 -352
  356. package/pi.dev-src/pi-mono/coding-agent/src/main.ts +0 -731
  357. package/pi.dev-src/pi-mono/coding-agent/src/migrations.ts +0 -314
  358. package/pi.dev-src/pi-mono/coding-agent/src/modes/index.ts +0 -9
  359. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/assets/clankolas.png +0 -0
  360. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/armin.ts +0 -382
  361. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/assistant-message.ts +0 -147
  362. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/bash-execution.ts +0 -218
  363. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/bordered-loader.ts +0 -68
  364. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/branch-summary-message.ts +0 -58
  365. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/compaction-summary-message.ts +0 -59
  366. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/config-selector.ts +0 -592
  367. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/countdown-timer.ts +0 -38
  368. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/custom-editor.ts +0 -80
  369. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/custom-message.ts +0 -99
  370. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/daxnuts.ts +0 -164
  371. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/diff.ts +0 -147
  372. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/dynamic-border.ts +0 -25
  373. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/earendil-announcement.ts +0 -53
  374. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/extension-editor.ts +0 -147
  375. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/extension-input.ts +0 -87
  376. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/extension-selector.ts +0 -107
  377. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/footer.ts +0 -220
  378. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/index.ts +0 -32
  379. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/keybinding-hints.ts +0 -24
  380. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/login-dialog.ts +0 -178
  381. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/model-selector.ts +0 -338
  382. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/oauth-selector.ts +0 -121
  383. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/scoped-models-selector.ts +0 -355
  384. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/session-selector-search.ts +0 -194
  385. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/session-selector.ts +0 -1026
  386. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/settings-selector.ts +0 -456
  387. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/show-images-selector.ts +0 -50
  388. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/skill-invocation-message.ts +0 -55
  389. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/theme-selector.ts +0 -67
  390. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/thinking-selector.ts +0 -74
  391. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/tool-execution.ts +0 -352
  392. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/tree-selector.ts +0 -1246
  393. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/user-message-selector.ts +0 -155
  394. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/user-message.ts +0 -35
  395. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/visual-truncate.ts +0 -50
  396. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/interactive-mode.ts +0 -5155
  397. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/dark.json +0 -85
  398. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/light.json +0 -84
  399. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  400. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/theme.ts +0 -1141
  401. package/pi.dev-src/pi-mono/coding-agent/src/modes/print-mode.ts +0 -158
  402. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/jsonl.ts +0 -58
  403. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/rpc-client.ts +0 -515
  404. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/rpc-mode.ts +0 -745
  405. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/rpc-types.ts +0 -264
  406. package/pi.dev-src/pi-mono/coding-agent/src/package-manager-cli.ts +0 -270
  407. package/pi.dev-src/pi-mono/coding-agent/src/utils/changelog.ts +0 -99
  408. package/pi.dev-src/pi-mono/coding-agent/src/utils/child-process.ts +0 -86
  409. package/pi.dev-src/pi-mono/coding-agent/src/utils/clipboard-image.ts +0 -300
  410. package/pi.dev-src/pi-mono/coding-agent/src/utils/clipboard-native.ts +0 -22
  411. package/pi.dev-src/pi-mono/coding-agent/src/utils/clipboard.ts +0 -81
  412. package/pi.dev-src/pi-mono/coding-agent/src/utils/exif-orientation.ts +0 -183
  413. package/pi.dev-src/pi-mono/coding-agent/src/utils/frontmatter.ts +0 -39
  414. package/pi.dev-src/pi-mono/coding-agent/src/utils/fs-watch.ts +0 -30
  415. package/pi.dev-src/pi-mono/coding-agent/src/utils/git.ts +0 -192
  416. package/pi.dev-src/pi-mono/coding-agent/src/utils/image-convert.ts +0 -41
  417. package/pi.dev-src/pi-mono/coding-agent/src/utils/image-resize.ts +0 -176
  418. package/pi.dev-src/pi-mono/coding-agent/src/utils/mime.ts +0 -30
  419. package/pi.dev-src/pi-mono/coding-agent/src/utils/paths.ts +0 -20
  420. package/pi.dev-src/pi-mono/coding-agent/src/utils/photon.ts +0 -139
  421. package/pi.dev-src/pi-mono/coding-agent/src/utils/shell.ts +0 -210
  422. package/pi.dev-src/pi-mono/coding-agent/src/utils/sleep.ts +0 -18
  423. package/pi.dev-src/pi-mono/coding-agent/src/utils/tools-manager.ts +0 -287
  424. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-auto-compaction-queue.test.ts +0 -437
  425. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-branching.test.ts +0 -156
  426. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-compaction.test.ts +0 -208
  427. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-concurrent.test.ts +0 -618
  428. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-dynamic-provider.test.ts +0 -117
  429. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-dynamic-tools.test.ts +0 -182
  430. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-retry.test.ts +0 -318
  431. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-runtime-events.test.ts +0 -208
  432. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-stats.test.ts +0 -143
  433. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-tree-navigation.test.ts +0 -323
  434. package/pi.dev-src/pi-mono/coding-agent/test/args.test.ts +0 -328
  435. package/pi.dev-src/pi-mono/coding-agent/test/assistant-message.test.ts +0 -57
  436. package/pi.dev-src/pi-mono/coding-agent/test/auth-storage.test.ts +0 -462
  437. package/pi.dev-src/pi-mono/coding-agent/test/bash-close-hang-windows.test.ts +0 -126
  438. package/pi.dev-src/pi-mono/coding-agent/test/bash-execution-width.test.ts +0 -80
  439. package/pi.dev-src/pi-mono/coding-agent/test/block-images.test.ts +0 -120
  440. package/pi.dev-src/pi-mono/coding-agent/test/clipboard-image-bmp-conversion.test.ts +0 -88
  441. package/pi.dev-src/pi-mono/coding-agent/test/clipboard-image.test.ts +0 -136
  442. package/pi.dev-src/pi-mono/coding-agent/test/compaction-extensions-example.test.ts +0 -66
  443. package/pi.dev-src/pi-mono/coding-agent/test/compaction-extensions.test.ts +0 -415
  444. package/pi.dev-src/pi-mono/coding-agent/test/compaction-serialization.test.ts +0 -79
  445. package/pi.dev-src/pi-mono/coding-agent/test/compaction-summary-reasoning.test.ts +0 -118
  446. package/pi.dev-src/pi-mono/coding-agent/test/compaction-thinking-model.test.ts +0 -223
  447. package/pi.dev-src/pi-mono/coding-agent/test/compaction.test.ts +0 -550
  448. package/pi.dev-src/pi-mono/coding-agent/test/config.test.ts +0 -30
  449. package/pi.dev-src/pi-mono/coding-agent/test/edit-tool-legacy-input.test.ts +0 -116
  450. package/pi.dev-src/pi-mono/coding-agent/test/edit-tool-no-full-redraw.test.ts +0 -235
  451. package/pi.dev-src/pi-mono/coding-agent/test/export-html-whitespace.test.ts +0 -12
  452. package/pi.dev-src/pi-mono/coding-agent/test/export-html-xss.test.ts +0 -28
  453. package/pi.dev-src/pi-mono/coding-agent/test/extensions-discovery.test.ts +0 -463
  454. package/pi.dev-src/pi-mono/coding-agent/test/extensions-input-event.test.ts +0 -112
  455. package/pi.dev-src/pi-mono/coding-agent/test/extensions-runner.test.ts +0 -805
  456. package/pi.dev-src/pi-mono/coding-agent/test/file-mutation-queue.test.ts +0 -163
  457. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/assistant-message-with-thinking-code.json +0 -33
  458. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/before-compaction.jsonl +0 -1003
  459. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/empty-agent/.gitkeep +0 -0
  460. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/empty-cwd/.gitkeep +0 -0
  461. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/large-session.jsonl +0 -1019
  462. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/consecutive-hyphens/SKILL.md +0 -8
  463. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/disable-model-invocation/SKILL.md +0 -9
  464. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/invalid-name-chars/SKILL.md +0 -8
  465. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/invalid-yaml/SKILL.md +0 -8
  466. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/long-name/SKILL.md +0 -8
  467. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/missing-description/SKILL.md +0 -7
  468. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/multiline-description/SKILL.md +0 -11
  469. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/name-mismatch/SKILL.md +0 -8
  470. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/nested/child-skill/SKILL.md +0 -8
  471. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/no-frontmatter/SKILL.md +0 -3
  472. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/root-skill-preferred/SKILL.md +0 -3
  473. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/root-skill-preferred/nested-child/SKILL.md +0 -3
  474. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/unknown-field/SKILL.md +0 -10
  475. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/valid-skill/SKILL.md +0 -8
  476. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills-collision/first/calendar/SKILL.md +0 -8
  477. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills-collision/second/calendar/SKILL.md +0 -8
  478. package/pi.dev-src/pi-mono/coding-agent/test/footer-data-provider.test.ts +0 -265
  479. package/pi.dev-src/pi-mono/coding-agent/test/footer-width.test.ts +0 -115
  480. package/pi.dev-src/pi-mono/coding-agent/test/frontmatter.test.ts +0 -60
  481. package/pi.dev-src/pi-mono/coding-agent/test/git-ssh-url.test.ts +0 -78
  482. package/pi.dev-src/pi-mono/coding-agent/test/git-update.test.ts +0 -411
  483. package/pi.dev-src/pi-mono/coding-agent/test/image-processing.test.ts +0 -145
  484. package/pi.dev-src/pi-mono/coding-agent/test/image-resize-callers.test.ts +0 -53
  485. package/pi.dev-src/pi-mono/coding-agent/test/initial-message.test.ts +0 -48
  486. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-anthropic-warning.test.ts +0 -73
  487. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-clone-command.test.ts +0 -77
  488. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-compaction.test.ts +0 -57
  489. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-import-command.test.ts +0 -144
  490. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-status.test.ts +0 -635
  491. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-suspend.test.ts +0 -149
  492. package/pi.dev-src/pi-mono/coding-agent/test/keybindings-migration.test.ts +0 -88
  493. package/pi.dev-src/pi-mono/coding-agent/test/model-registry.test.ts +0 -1209
  494. package/pi.dev-src/pi-mono/coding-agent/test/model-resolver.test.ts +0 -436
  495. package/pi.dev-src/pi-mono/coding-agent/test/package-command-paths.test.ts +0 -144
  496. package/pi.dev-src/pi-mono/coding-agent/test/package-manager-ssh.test.ts +0 -97
  497. package/pi.dev-src/pi-mono/coding-agent/test/package-manager.test.ts +0 -1795
  498. package/pi.dev-src/pi-mono/coding-agent/test/path-utils.test.ts +0 -162
  499. package/pi.dev-src/pi-mono/coding-agent/test/plan-mode-utils.test.ts +0 -261
  500. package/pi.dev-src/pi-mono/coding-agent/test/print-mode.test.ts +0 -140
  501. package/pi.dev-src/pi-mono/coding-agent/test/prompt-templates.test.ts +0 -515
  502. package/pi.dev-src/pi-mono/coding-agent/test/resource-loader.test.ts +0 -576
  503. package/pi.dev-src/pi-mono/coding-agent/test/rpc-client-clone.test.ts +0 -29
  504. package/pi.dev-src/pi-mono/coding-agent/test/rpc-example.ts +0 -86
  505. package/pi.dev-src/pi-mono/coding-agent/test/rpc-jsonl.test.ts +0 -65
  506. package/pi.dev-src/pi-mono/coding-agent/test/rpc-prompt-response-semantics.test.ts +0 -285
  507. package/pi.dev-src/pi-mono/coding-agent/test/rpc.test.ts +0 -321
  508. package/pi.dev-src/pi-mono/coding-agent/test/sdk-codex-cache-probe-tool-loop.ts +0 -364
  509. package/pi.dev-src/pi-mono/coding-agent/test/sdk-openrouter-attribution.test.ts +0 -181
  510. package/pi.dev-src/pi-mono/coding-agent/test/sdk-session-manager.test.ts +0 -95
  511. package/pi.dev-src/pi-mono/coding-agent/test/sdk-skills.test.ts +0 -109
  512. package/pi.dev-src/pi-mono/coding-agent/test/session-cwd.test.ts +0 -91
  513. package/pi.dev-src/pi-mono/coding-agent/test/session-info-modified-timestamp.test.ts +0 -83
  514. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/build-context.test.ts +0 -268
  515. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/custom-session-id.test.ts +0 -109
  516. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/file-operations.test.ts +0 -208
  517. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/labels.test.ts +0 -198
  518. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/migration.test.ts +0 -78
  519. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/save-entry.test.ts +0 -55
  520. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/tree-traversal.test.ts +0 -533
  521. package/pi.dev-src/pi-mono/coding-agent/test/session-selector-path-delete.test.ts +0 -315
  522. package/pi.dev-src/pi-mono/coding-agent/test/session-selector-rename.test.ts +0 -111
  523. package/pi.dev-src/pi-mono/coding-agent/test/session-selector-search.test.ts +0 -195
  524. package/pi.dev-src/pi-mono/coding-agent/test/settings-manager-bug.test.ts +0 -147
  525. package/pi.dev-src/pi-mono/coding-agent/test/settings-manager.test.ts +0 -319
  526. package/pi.dev-src/pi-mono/coding-agent/test/skills.test.ts +0 -432
  527. package/pi.dev-src/pi-mono/coding-agent/test/stdout-cleanliness.test.ts +0 -103
  528. package/pi.dev-src/pi-mono/coding-agent/test/streaming-render-debug.ts +0 -97
  529. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-bash-persistence.test.ts +0 -242
  530. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-compaction.test.ts +0 -343
  531. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-model-extension.test.ts +0 -325
  532. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-prompt.test.ts +0 -323
  533. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-queue.test.ts +0 -422
  534. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-retry-events.test.ts +0 -358
  535. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-runtime.test.ts +0 -553
  536. package/pi.dev-src/pi-mono/coding-agent/test/suite/harness.ts +0 -208
  537. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2023-queued-slash-command-followup.test.ts +0 -80
  538. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2753-reload-stale-resource-settings.test.ts +0 -100
  539. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2781-skill-collision-precedence.test.ts +0 -120
  540. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2791-fswatch-error-crash.test.ts +0 -106
  541. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2835-tools-allowlist-filters-extension-tools.test.ts +0 -94
  542. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2860-replaced-session-context.test.ts +0 -274
  543. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3217-scoped-model-order.test.ts +0 -104
  544. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3302-find-path-glob.test.ts +0 -72
  545. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3303-find-nested-gitignore.test.ts +0 -83
  546. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3317-network-connection-lost-retry.test.ts +0 -33
  547. package/pi.dev-src/pi-mono/coding-agent/test/system-prompt.test.ts +0 -102
  548. package/pi.dev-src/pi-mono/coding-agent/test/test-harness.test.ts +0 -321
  549. package/pi.dev-src/pi-mono/coding-agent/test/test-harness.ts +0 -446
  550. package/pi.dev-src/pi-mono/coding-agent/test/test-theme-colors.ts +0 -246
  551. package/pi.dev-src/pi-mono/coding-agent/test/theme-export.test.ts +0 -104
  552. package/pi.dev-src/pi-mono/coding-agent/test/tool-execution-component.test.ts +0 -331
  553. package/pi.dev-src/pi-mono/coding-agent/test/tools.test.ts +0 -889
  554. package/pi.dev-src/pi-mono/coding-agent/test/tree-selector.test.ts +0 -655
  555. package/pi.dev-src/pi-mono/coding-agent/test/trigger-compact-extension.test.ts +0 -57
  556. package/pi.dev-src/pi-mono/coding-agent/test/truncate-to-width.test.ts +0 -81
  557. package/pi.dev-src/pi-mono/coding-agent/test/user-message.test.ts +0 -25
  558. package/pi.dev-src/pi-mono/coding-agent/test/utilities.ts +0 -316
  559. package/pi.dev-src/pi-mono/coding-agent/tsconfig.examples.json +0 -16
  560. package/pi.dev-src/pi-mono/coding-agent/vitest.config.ts +0 -26
  561. package/pi.dev-src/pi-mono/mom/dev.sh +0 -30
  562. package/pi.dev-src/pi-mono/mom/docker.sh +0 -95
  563. package/pi.dev-src/pi-mono/mom/scripts/migrate-timestamps.ts +0 -121
  564. package/pi.dev-src/pi-mono/mom/src/agent.ts +0 -882
  565. package/pi.dev-src/pi-mono/mom/src/context.ts +0 -180
  566. package/pi.dev-src/pi-mono/mom/src/download.ts +0 -117
  567. package/pi.dev-src/pi-mono/mom/src/events.ts +0 -442
  568. package/pi.dev-src/pi-mono/mom/src/fs-watch.ts +0 -30
  569. package/pi.dev-src/pi-mono/mom/src/log.ts +0 -271
  570. package/pi.dev-src/pi-mono/mom/src/main.ts +0 -367
  571. package/pi.dev-src/pi-mono/mom/src/sandbox.ts +0 -221
  572. package/pi.dev-src/pi-mono/mom/src/slack.ts +0 -623
  573. package/pi.dev-src/pi-mono/mom/src/store.ts +0 -234
  574. package/pi.dev-src/pi-mono/mom/src/tools/attach.ts +0 -47
  575. package/pi.dev-src/pi-mono/mom/src/tools/bash.ts +0 -97
  576. package/pi.dev-src/pi-mono/mom/src/tools/edit.ts +0 -165
  577. package/pi.dev-src/pi-mono/mom/src/tools/index.ts +0 -19
  578. package/pi.dev-src/pi-mono/mom/src/tools/read.ts +0 -159
  579. package/pi.dev-src/pi-mono/mom/src/tools/truncate.ts +0 -236
  580. package/pi.dev-src/pi-mono/mom/src/tools/write.ts +0 -45
  581. package/pi.dev-src/pi-mono/mom/test/events.test.ts +0 -50
  582. package/pi.dev-src/pi-mono/pods/scripts/model_run.sh +0 -83
  583. package/pi.dev-src/pi-mono/pods/scripts/pod_setup.sh +0 -336
  584. package/pi.dev-src/pi-mono/pods/src/cli.ts +0 -360
  585. package/pi.dev-src/pi-mono/pods/src/commands/models.ts +0 -753
  586. package/pi.dev-src/pi-mono/pods/src/commands/pods.ts +0 -205
  587. package/pi.dev-src/pi-mono/pods/src/commands/prompt.ts +0 -84
  588. package/pi.dev-src/pi-mono/pods/src/config.ts +0 -80
  589. package/pi.dev-src/pi-mono/pods/src/index.ts +0 -2
  590. package/pi.dev-src/pi-mono/pods/src/model-configs.ts +0 -111
  591. package/pi.dev-src/pi-mono/pods/src/models.json +0 -295
  592. package/pi.dev-src/pi-mono/pods/src/ssh.ts +0 -151
  593. package/pi.dev-src/pi-mono/pods/src/types.ts +0 -27
  594. package/pi.dev-src/pi-mono/tui/src/autocomplete.ts +0 -783
  595. package/pi.dev-src/pi-mono/tui/src/components/box.ts +0 -137
  596. package/pi.dev-src/pi-mono/tui/src/components/cancellable-loader.ts +0 -40
  597. package/pi.dev-src/pi-mono/tui/src/components/editor.ts +0 -2280
  598. package/pi.dev-src/pi-mono/tui/src/components/image.ts +0 -104
  599. package/pi.dev-src/pi-mono/tui/src/components/input.ts +0 -503
  600. package/pi.dev-src/pi-mono/tui/src/components/loader.ts +0 -86
  601. package/pi.dev-src/pi-mono/tui/src/components/markdown.ts +0 -852
  602. package/pi.dev-src/pi-mono/tui/src/components/select-list.ts +0 -229
  603. package/pi.dev-src/pi-mono/tui/src/components/settings-list.ts +0 -250
  604. package/pi.dev-src/pi-mono/tui/src/components/spacer.ts +0 -28
  605. package/pi.dev-src/pi-mono/tui/src/components/text.ts +0 -106
  606. package/pi.dev-src/pi-mono/tui/src/components/truncated-text.ts +0 -65
  607. package/pi.dev-src/pi-mono/tui/src/editor-component.ts +0 -74
  608. package/pi.dev-src/pi-mono/tui/src/fuzzy.ts +0 -133
  609. package/pi.dev-src/pi-mono/tui/src/index.ts +0 -106
  610. package/pi.dev-src/pi-mono/tui/src/keybindings.ts +0 -244
  611. package/pi.dev-src/pi-mono/tui/src/keys.ts +0 -1400
  612. package/pi.dev-src/pi-mono/tui/src/kill-ring.ts +0 -46
  613. package/pi.dev-src/pi-mono/tui/src/stdin-buffer.ts +0 -386
  614. package/pi.dev-src/pi-mono/tui/src/terminal-image.ts +0 -414
  615. package/pi.dev-src/pi-mono/tui/src/terminal.ts +0 -373
  616. package/pi.dev-src/pi-mono/tui/src/tui.ts +0 -1243
  617. package/pi.dev-src/pi-mono/tui/src/undo-stack.ts +0 -28
  618. package/pi.dev-src/pi-mono/tui/src/utils.ts +0 -1085
  619. package/pi.dev-src/pi-mono/tui/test/autocomplete.test.ts +0 -542
  620. package/pi.dev-src/pi-mono/tui/test/bug-regression-isimageline-startswith-bug.test.ts +0 -237
  621. package/pi.dev-src/pi-mono/tui/test/chat-simple.ts +0 -129
  622. package/pi.dev-src/pi-mono/tui/test/editor.test.ts +0 -3812
  623. package/pi.dev-src/pi-mono/tui/test/fuzzy.test.ts +0 -98
  624. package/pi.dev-src/pi-mono/tui/test/image-test.ts +0 -56
  625. package/pi.dev-src/pi-mono/tui/test/input.test.ts +0 -580
  626. package/pi.dev-src/pi-mono/tui/test/key-tester.ts +0 -105
  627. package/pi.dev-src/pi-mono/tui/test/keybindings.test.ts +0 -38
  628. package/pi.dev-src/pi-mono/tui/test/keys.test.ts +0 -614
  629. package/pi.dev-src/pi-mono/tui/test/markdown.test.ts +0 -1236
  630. package/pi.dev-src/pi-mono/tui/test/overlay-non-capturing.test.ts +0 -609
  631. package/pi.dev-src/pi-mono/tui/test/overlay-options.test.ts +0 -538
  632. package/pi.dev-src/pi-mono/tui/test/overlay-short-content.test.ts +0 -56
  633. package/pi.dev-src/pi-mono/tui/test/regression-regional-indicator-width.test.ts +0 -52
  634. package/pi.dev-src/pi-mono/tui/test/select-list.test.ts +0 -116
  635. package/pi.dev-src/pi-mono/tui/test/stdin-buffer.test.ts +0 -422
  636. package/pi.dev-src/pi-mono/tui/test/terminal-image.test.ts +0 -279
  637. package/pi.dev-src/pi-mono/tui/test/test-themes.ts +0 -38
  638. package/pi.dev-src/pi-mono/tui/test/truncate-to-width.test.ts +0 -62
  639. package/pi.dev-src/pi-mono/tui/test/truncated-text.test.ts +0 -129
  640. package/pi.dev-src/pi-mono/tui/test/tui-cell-size-input.test.ts +0 -81
  641. package/pi.dev-src/pi-mono/tui/test/tui-overlay-style-leak.test.ts +0 -72
  642. package/pi.dev-src/pi-mono/tui/test/tui-render.test.ts +0 -509
  643. package/pi.dev-src/pi-mono/tui/test/viewport-overwrite-repro.ts +0 -106
  644. package/pi.dev-src/pi-mono/tui/test/virtual-terminal.ts +0 -218
  645. package/pi.dev-src/pi-mono/tui/test/wrap-ansi.test.ts +0 -207
  646. package/pi.dev-src/pi-mono/tui/vitest.config.ts +0 -7
  647. package/pi.dev-src/pi-mono/web-ui/example/index.html +0 -13
  648. package/pi.dev-src/pi-mono/web-ui/example/src/app.css +0 -1
  649. package/pi.dev-src/pi-mono/web-ui/example/src/custom-messages.ts +0 -99
  650. package/pi.dev-src/pi-mono/web-ui/example/src/main.ts +0 -421
  651. package/pi.dev-src/pi-mono/web-ui/example/tsconfig.json +0 -23
  652. package/pi.dev-src/pi-mono/web-ui/example/vite.config.ts +0 -6
  653. package/pi.dev-src/pi-mono/web-ui/scripts/count-prompt-tokens.ts +0 -88
  654. package/pi.dev-src/pi-mono/web-ui/src/ChatPanel.ts +0 -209
  655. package/pi.dev-src/pi-mono/web-ui/src/app.css +0 -68
  656. package/pi.dev-src/pi-mono/web-ui/src/components/AgentInterface.ts +0 -403
  657. package/pi.dev-src/pi-mono/web-ui/src/components/AttachmentTile.ts +0 -107
  658. package/pi.dev-src/pi-mono/web-ui/src/components/ConsoleBlock.ts +0 -72
  659. package/pi.dev-src/pi-mono/web-ui/src/components/CustomProviderCard.ts +0 -100
  660. package/pi.dev-src/pi-mono/web-ui/src/components/ExpandableSection.ts +0 -46
  661. package/pi.dev-src/pi-mono/web-ui/src/components/Input.ts +0 -113
  662. package/pi.dev-src/pi-mono/web-ui/src/components/MessageEditor.ts +0 -405
  663. package/pi.dev-src/pi-mono/web-ui/src/components/MessageList.ts +0 -98
  664. package/pi.dev-src/pi-mono/web-ui/src/components/Messages.ts +0 -383
  665. package/pi.dev-src/pi-mono/web-ui/src/components/ProviderKeyInput.ts +0 -153
  666. package/pi.dev-src/pi-mono/web-ui/src/components/SandboxedIframe.ts +0 -626
  667. package/pi.dev-src/pi-mono/web-ui/src/components/StreamingMessageContainer.ts +0 -103
  668. package/pi.dev-src/pi-mono/web-ui/src/components/ThinkingBlock.ts +0 -43
  669. package/pi.dev-src/pi-mono/web-ui/src/components/message-renderer-registry.ts +0 -28
  670. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts +0 -220
  671. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/AttachmentsRuntimeProvider.ts +0 -66
  672. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/ConsoleRuntimeProvider.ts +0 -186
  673. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/FileDownloadRuntimeProvider.ts +0 -110
  674. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/RuntimeMessageBridge.ts +0 -82
  675. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/RuntimeMessageRouter.ts +0 -216
  676. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/SandboxRuntimeProvider.ts +0 -52
  677. package/pi.dev-src/pi-mono/web-ui/src/dialogs/ApiKeyPromptDialog.ts +0 -75
  678. package/pi.dev-src/pi-mono/web-ui/src/dialogs/AttachmentOverlay.ts +0 -636
  679. package/pi.dev-src/pi-mono/web-ui/src/dialogs/CustomProviderDialog.ts +0 -274
  680. package/pi.dev-src/pi-mono/web-ui/src/dialogs/ModelSelector.ts +0 -370
  681. package/pi.dev-src/pi-mono/web-ui/src/dialogs/PersistentStorageDialog.ts +0 -144
  682. package/pi.dev-src/pi-mono/web-ui/src/dialogs/ProvidersModelsTab.ts +0 -212
  683. package/pi.dev-src/pi-mono/web-ui/src/dialogs/SessionListDialog.ts +0 -150
  684. package/pi.dev-src/pi-mono/web-ui/src/dialogs/SettingsDialog.ts +0 -218
  685. package/pi.dev-src/pi-mono/web-ui/src/index.ts +0 -120
  686. package/pi.dev-src/pi-mono/web-ui/src/prompts/prompts.ts +0 -282
  687. package/pi.dev-src/pi-mono/web-ui/src/storage/app-storage.ts +0 -60
  688. package/pi.dev-src/pi-mono/web-ui/src/storage/backends/indexeddb-storage-backend.ts +0 -193
  689. package/pi.dev-src/pi-mono/web-ui/src/storage/store.ts +0 -33
  690. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/custom-providers-store.ts +0 -62
  691. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/provider-keys-store.ts +0 -33
  692. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/sessions-store.ts +0 -136
  693. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/settings-store.ts +0 -34
  694. package/pi.dev-src/pi-mono/web-ui/src/storage/types.ts +0 -206
  695. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ArtifactElement.ts +0 -14
  696. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ArtifactPill.ts +0 -26
  697. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/Console.ts +0 -93
  698. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/DocxArtifact.ts +0 -213
  699. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ExcelArtifact.ts +0 -231
  700. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/GenericArtifact.ts +0 -117
  701. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/HtmlArtifact.ts +0 -195
  702. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ImageArtifact.ts +0 -116
  703. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/MarkdownArtifact.ts +0 -82
  704. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/PdfArtifact.ts +0 -201
  705. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/SvgArtifact.ts +0 -119
  706. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/TextArtifact.ts +0 -148
  707. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/artifacts-tool-renderer.ts +0 -310
  708. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/artifacts.ts +0 -713
  709. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/index.ts +0 -7
  710. package/pi.dev-src/pi-mono/web-ui/src/tools/extract-document.ts +0 -275
  711. package/pi.dev-src/pi-mono/web-ui/src/tools/index.ts +0 -46
  712. package/pi.dev-src/pi-mono/web-ui/src/tools/javascript-repl.ts +0 -293
  713. package/pi.dev-src/pi-mono/web-ui/src/tools/renderer-registry.ts +0 -130
  714. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/BashRenderer.ts +0 -52
  715. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/CalculateRenderer.ts +0 -58
  716. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/DefaultRenderer.ts +0 -103
  717. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/GetCurrentTimeRenderer.ts +0 -92
  718. package/pi.dev-src/pi-mono/web-ui/src/tools/types.ts +0 -15
  719. package/pi.dev-src/pi-mono/web-ui/src/utils/attachment-utils.ts +0 -472
  720. package/pi.dev-src/pi-mono/web-ui/src/utils/auth-token.ts +0 -22
  721. package/pi.dev-src/pi-mono/web-ui/src/utils/format.ts +0 -42
  722. package/pi.dev-src/pi-mono/web-ui/src/utils/i18n.ts +0 -653
  723. package/pi.dev-src/pi-mono/web-ui/src/utils/model-discovery.ts +0 -277
  724. package/pi.dev-src/pi-mono/web-ui/src/utils/proxy-utils.ts +0 -139
  725. package/pi.dev-src/pi-mono/web-ui/src/utils/test-sessions.ts +0 -2357
  726. package/pi.dev-src/pi-mono/web-ui/tsconfig.json +0 -7
  727. package/tests/attended-results-scenarios.ts +0 -648
  728. package/tests/attended-results.test.ts +0 -39
  729. package/tests/cli-command-option-parity.test.ts +0 -798
  730. package/tests/debug-extension-harness.test.ts +0 -466
  731. package/tests/extension-registration.test.ts +0 -6785
  732. package/tests/fixtures/fixture_c.c +0 -361
  733. package/tests/fixtures/fixture_cpp.cpp +0 -407
  734. package/tests/fixtures/fixture_csharp.cs +0 -411
  735. package/tests/fixtures/fixture_elixir.ex +0 -409
  736. package/tests/fixtures/fixture_go.go +0 -341
  737. package/tests/fixtures/fixture_haskell.hs +0 -250
  738. package/tests/fixtures/fixture_java.java +0 -430
  739. package/tests/fixtures/fixture_javascript.js +0 -383
  740. package/tests/fixtures/fixture_kotlin.kt +0 -451
  741. package/tests/fixtures/fixture_lua.lua +0 -276
  742. package/tests/fixtures/fixture_perl.pl +0 -310
  743. package/tests/fixtures/fixture_php.php +0 -433
  744. package/tests/fixtures/fixture_python.py +0 -502
  745. package/tests/fixtures/fixture_ruby.rb +0 -345
  746. package/tests/fixtures/fixture_rust.rs +0 -380
  747. package/tests/fixtures/fixture_scala.scala +0 -398
  748. package/tests/fixtures/fixture_shell.sh +0 -276
  749. package/tests/fixtures/fixture_swift.swift +0 -397
  750. package/tests/fixtures/fixture_typescript.ts +0 -434
  751. package/tests/fixtures/fixture_zig.zig +0 -295
  752. package/tests/fixtures_attended_results/project/compress-line-numbers.json +0 -5
  753. package/tests/fixtures_attended_results/project/compress.json +0 -5
  754. package/tests/fixtures_attended_results/project/enable-static-check-invalid-command.json +0 -5
  755. package/tests/fixtures_attended_results/project/enable-static-check-valid.json +0 -5
  756. package/tests/fixtures_attended_results/project/files-static-check.json +0 -5
  757. package/tests/fixtures_attended_results/project/find-line-numbers.json +0 -5
  758. package/tests/fixtures_attended_results/project/find.json +0 -5
  759. package/tests/fixtures_attended_results/project/get-base-path.json +0 -5
  760. package/tests/fixtures_attended_results/project/git-check-clean.json +0 -5
  761. package/tests/fixtures_attended_results/project/git-check-dirty.json +0 -5
  762. package/tests/fixtures_attended_results/project/git-path.json +0 -5
  763. package/tests/fixtures_attended_results/project/git-wt-create-invalid.json +0 -5
  764. package/tests/fixtures_attended_results/project/git-wt-create-valid.json +0 -5
  765. package/tests/fixtures_attended_results/project/git-wt-delete-nonexistent.json +0 -5
  766. package/tests/fixtures_attended_results/project/git-wt-delete-valid.json +0 -5
  767. package/tests/fixtures_attended_results/project/git-wt-name.json +0 -5
  768. package/tests/fixtures_attended_results/project/static-check.json +0 -5
  769. package/tests/fixtures_attended_results/project/summarize.json +0 -5
  770. package/tests/fixtures_attended_results/project/tokens.json +0 -5
  771. package/tests/fixtures_attended_results/standalone/files-compress/fixture_c.c.json +0 -5
  772. package/tests/fixtures_attended_results/standalone/files-compress/fixture_cpp.cpp.json +0 -5
  773. package/tests/fixtures_attended_results/standalone/files-compress/fixture_csharp.cs.json +0 -5
  774. package/tests/fixtures_attended_results/standalone/files-compress/fixture_elixir.ex.json +0 -5
  775. package/tests/fixtures_attended_results/standalone/files-compress/fixture_go.go.json +0 -5
  776. package/tests/fixtures_attended_results/standalone/files-compress/fixture_haskell.hs.json +0 -5
  777. package/tests/fixtures_attended_results/standalone/files-compress/fixture_java.java.json +0 -5
  778. package/tests/fixtures_attended_results/standalone/files-compress/fixture_javascript.js.json +0 -5
  779. package/tests/fixtures_attended_results/standalone/files-compress/fixture_kotlin.kt.json +0 -5
  780. package/tests/fixtures_attended_results/standalone/files-compress/fixture_lua.lua.json +0 -5
  781. package/tests/fixtures_attended_results/standalone/files-compress/fixture_perl.pl.json +0 -5
  782. package/tests/fixtures_attended_results/standalone/files-compress/fixture_php.php.json +0 -5
  783. package/tests/fixtures_attended_results/standalone/files-compress/fixture_python.py.json +0 -5
  784. package/tests/fixtures_attended_results/standalone/files-compress/fixture_ruby.rb.json +0 -5
  785. package/tests/fixtures_attended_results/standalone/files-compress/fixture_rust.rs.json +0 -5
  786. package/tests/fixtures_attended_results/standalone/files-compress/fixture_scala.scala.json +0 -5
  787. package/tests/fixtures_attended_results/standalone/files-compress/fixture_shell.sh.json +0 -5
  788. package/tests/fixtures_attended_results/standalone/files-compress/fixture_swift.swift.json +0 -5
  789. package/tests/fixtures_attended_results/standalone/files-compress/fixture_typescript.ts.json +0 -5
  790. package/tests/fixtures_attended_results/standalone/files-compress/fixture_zig.zig.json +0 -5
  791. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_c.c.json +0 -5
  792. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_cpp.cpp.json +0 -5
  793. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_csharp.cs.json +0 -5
  794. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_elixir.ex.json +0 -5
  795. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_go.go.json +0 -5
  796. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_haskell.hs.json +0 -5
  797. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_java.java.json +0 -5
  798. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_javascript.js.json +0 -5
  799. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_kotlin.kt.json +0 -5
  800. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_lua.lua.json +0 -5
  801. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_perl.pl.json +0 -5
  802. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_php.php.json +0 -5
  803. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_python.py.json +0 -5
  804. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_ruby.rb.json +0 -5
  805. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_rust.rs.json +0 -5
  806. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_scala.scala.json +0 -5
  807. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_shell.sh.json +0 -5
  808. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_swift.swift.json +0 -5
  809. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_typescript.ts.json +0 -5
  810. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_zig.zig.json +0 -5
  811. package/tests/fixtures_attended_results/standalone/files-find/fixture_c.c.json +0 -5
  812. package/tests/fixtures_attended_results/standalone/files-find/fixture_cpp.cpp.json +0 -5
  813. package/tests/fixtures_attended_results/standalone/files-find/fixture_csharp.cs.json +0 -5
  814. package/tests/fixtures_attended_results/standalone/files-find/fixture_elixir.ex.json +0 -5
  815. package/tests/fixtures_attended_results/standalone/files-find/fixture_go.go.json +0 -5
  816. package/tests/fixtures_attended_results/standalone/files-find/fixture_haskell.hs.json +0 -5
  817. package/tests/fixtures_attended_results/standalone/files-find/fixture_java.java.json +0 -5
  818. package/tests/fixtures_attended_results/standalone/files-find/fixture_javascript.js.json +0 -5
  819. package/tests/fixtures_attended_results/standalone/files-find/fixture_kotlin.kt.json +0 -5
  820. package/tests/fixtures_attended_results/standalone/files-find/fixture_lua.lua.json +0 -5
  821. package/tests/fixtures_attended_results/standalone/files-find/fixture_perl.pl.json +0 -5
  822. package/tests/fixtures_attended_results/standalone/files-find/fixture_php.php.json +0 -5
  823. package/tests/fixtures_attended_results/standalone/files-find/fixture_python.py.json +0 -5
  824. package/tests/fixtures_attended_results/standalone/files-find/fixture_ruby.rb.json +0 -5
  825. package/tests/fixtures_attended_results/standalone/files-find/fixture_rust.rs.json +0 -5
  826. package/tests/fixtures_attended_results/standalone/files-find/fixture_scala.scala.json +0 -5
  827. package/tests/fixtures_attended_results/standalone/files-find/fixture_shell.sh.json +0 -5
  828. package/tests/fixtures_attended_results/standalone/files-find/fixture_swift.swift.json +0 -5
  829. package/tests/fixtures_attended_results/standalone/files-find/fixture_typescript.ts.json +0 -5
  830. package/tests/fixtures_attended_results/standalone/files-find/fixture_zig.zig.json +0 -5
  831. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_c.c.json +0 -5
  832. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_cpp.cpp.json +0 -5
  833. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_csharp.cs.json +0 -5
  834. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_elixir.ex.json +0 -5
  835. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_go.go.json +0 -5
  836. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_haskell.hs.json +0 -5
  837. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_java.java.json +0 -5
  838. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_javascript.js.json +0 -5
  839. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_kotlin.kt.json +0 -5
  840. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_lua.lua.json +0 -5
  841. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_perl.pl.json +0 -5
  842. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_php.php.json +0 -5
  843. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_python.py.json +0 -5
  844. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_ruby.rb.json +0 -5
  845. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_rust.rs.json +0 -5
  846. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_scala.scala.json +0 -5
  847. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_shell.sh.json +0 -5
  848. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_swift.swift.json +0 -5
  849. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_typescript.ts.json +0 -5
  850. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_zig.zig.json +0 -5
  851. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_c.c.json +0 -5
  852. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_cpp.cpp.json +0 -5
  853. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_csharp.cs.json +0 -5
  854. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_elixir.ex.json +0 -5
  855. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_go.go.json +0 -5
  856. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_haskell.hs.json +0 -5
  857. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_java.java.json +0 -5
  858. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_javascript.js.json +0 -5
  859. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_kotlin.kt.json +0 -5
  860. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_lua.lua.json +0 -5
  861. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_perl.pl.json +0 -5
  862. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_php.php.json +0 -5
  863. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_python.py.json +0 -5
  864. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_ruby.rb.json +0 -5
  865. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_rust.rs.json +0 -5
  866. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_scala.scala.json +0 -5
  867. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_shell.sh.json +0 -5
  868. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_swift.swift.json +0 -5
  869. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_typescript.ts.json +0 -5
  870. package/tests/fixtures_attended_results/standalone/files-summarize/fixture_zig.zig.json +0 -5
  871. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_c.c.json +0 -5
  872. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_cpp.cpp.json +0 -5
  873. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_csharp.cs.json +0 -5
  874. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_elixir.ex.json +0 -5
  875. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_go.go.json +0 -5
  876. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_haskell.hs.json +0 -5
  877. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_java.java.json +0 -5
  878. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_javascript.js.json +0 -5
  879. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_kotlin.kt.json +0 -5
  880. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_lua.lua.json +0 -5
  881. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_perl.pl.json +0 -5
  882. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_php.php.json +0 -5
  883. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_python.py.json +0 -5
  884. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_ruby.rb.json +0 -5
  885. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_rust.rs.json +0 -5
  886. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_scala.scala.json +0 -5
  887. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_shell.sh.json +0 -5
  888. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_swift.swift.json +0 -5
  889. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_typescript.ts.json +0 -5
  890. package/tests/fixtures_attended_results/standalone/files-tokens/fixture_zig.zig.json +0 -5
  891. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_c.c.json +0 -5
  892. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_cpp.cpp.json +0 -5
  893. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_csharp.cs.json +0 -5
  894. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_elixir.ex.json +0 -5
  895. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_go.go.json +0 -5
  896. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_haskell.hs.json +0 -5
  897. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_java.java.json +0 -5
  898. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_javascript.js.json +0 -5
  899. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_kotlin.kt.json +0 -5
  900. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_lua.lua.json +0 -5
  901. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_perl.pl.json +0 -5
  902. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_php.php.json +0 -5
  903. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_python.py.json +0 -5
  904. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_ruby.rb.json +0 -5
  905. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_rust.rs.json +0 -5
  906. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_scala.scala.json +0 -5
  907. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_shell.sh.json +0 -5
  908. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_swift.swift.json +0 -5
  909. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_typescript.ts.json +0 -5
  910. package/tests/fixtures_attended_results/standalone/test-static-check-command/fixture_zig.zig.json +0 -5
  911. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_c.c.json +0 -5
  912. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_cpp.cpp.json +0 -5
  913. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_csharp.cs.json +0 -5
  914. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_elixir.ex.json +0 -5
  915. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_go.go.json +0 -5
  916. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_haskell.hs.json +0 -5
  917. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_java.java.json +0 -5
  918. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_javascript.js.json +0 -5
  919. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_kotlin.kt.json +0 -5
  920. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_lua.lua.json +0 -5
  921. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_perl.pl.json +0 -5
  922. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_php.php.json +0 -5
  923. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_python.py.json +0 -5
  924. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_ruby.rb.json +0 -5
  925. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_rust.rs.json +0 -5
  926. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_scala.scala.json +0 -5
  927. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_shell.sh.json +0 -5
  928. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_swift.swift.json +0 -5
  929. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_typescript.ts.json +0 -5
  930. package/tests/fixtures_attended_results/standalone/test-static-check-dummy/fixture_zig.zig.json +0 -5
  931. package/tests/helpers.ts +0 -236
  932. package/tests/oracle-project.test.ts +0 -67
  933. package/tests/oracle-standalone.test.ts +0 -68
  934. package/tests/prompt-command-summary.test.ts +0 -36
  935. package/tests/prompt-rendering.test.ts +0 -103
  936. package/tests/python_oracle_stubs/tiktoken.py +0 -76
  937. package/tests/release-workflow.test.ts +0 -195
  938. package/tests/static-check-bundled.test.ts +0 -332
@@ -1,1425 +0,0 @@
1
- import type { AgentMessage } from "@mariozechner/pi-agent-core";
2
- import type { ImageContent, Message, TextContent } from "@mariozechner/pi-ai";
3
- import { randomUUID } from "crypto";
4
- import {
5
- appendFileSync,
6
- closeSync,
7
- existsSync,
8
- mkdirSync,
9
- openSync,
10
- readdirSync,
11
- readFileSync,
12
- readSync,
13
- statSync,
14
- writeFileSync,
15
- } from "fs";
16
- import { readdir, readFile, stat } from "fs/promises";
17
- import { join, resolve } from "path";
18
- import { v7 as uuidv7 } from "uuid";
19
- import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
20
- import {
21
- type BashExecutionMessage,
22
- type CustomMessage,
23
- createBranchSummaryMessage,
24
- createCompactionSummaryMessage,
25
- createCustomMessage,
26
- } from "./messages.js";
27
-
28
- export const CURRENT_SESSION_VERSION = 3;
29
-
30
- export interface SessionHeader {
31
- type: "session";
32
- version?: number; // v1 sessions don't have this
33
- id: string;
34
- timestamp: string;
35
- cwd: string;
36
- parentSession?: string;
37
- }
38
-
39
- export interface NewSessionOptions {
40
- id?: string;
41
- parentSession?: string;
42
- }
43
-
44
- export interface SessionEntryBase {
45
- type: string;
46
- id: string;
47
- parentId: string | null;
48
- timestamp: string;
49
- }
50
-
51
- export interface SessionMessageEntry extends SessionEntryBase {
52
- type: "message";
53
- message: AgentMessage;
54
- }
55
-
56
- export interface ThinkingLevelChangeEntry extends SessionEntryBase {
57
- type: "thinking_level_change";
58
- thinkingLevel: string;
59
- }
60
-
61
- export interface ModelChangeEntry extends SessionEntryBase {
62
- type: "model_change";
63
- provider: string;
64
- modelId: string;
65
- }
66
-
67
- export interface CompactionEntry<T = unknown> extends SessionEntryBase {
68
- type: "compaction";
69
- summary: string;
70
- firstKeptEntryId: string;
71
- tokensBefore: number;
72
- /** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */
73
- details?: T;
74
- /** True if generated by an extension, undefined/false if pi-generated (backward compatible) */
75
- fromHook?: boolean;
76
- }
77
-
78
- export interface BranchSummaryEntry<T = unknown> extends SessionEntryBase {
79
- type: "branch_summary";
80
- fromId: string;
81
- summary: string;
82
- /** Extension-specific data (not sent to LLM) */
83
- details?: T;
84
- /** True if generated by an extension, false if pi-generated */
85
- fromHook?: boolean;
86
- }
87
-
88
- /**
89
- * Custom entry for extensions to store extension-specific data in the session.
90
- * Use customType to identify your extension's entries.
91
- *
92
- * Purpose: Persist extension state across session reloads. On reload, extensions can
93
- * scan entries for their customType and reconstruct internal state.
94
- *
95
- * Does NOT participate in LLM context (ignored by buildSessionContext).
96
- * For injecting content into context, see CustomMessageEntry.
97
- */
98
- export interface CustomEntry<T = unknown> extends SessionEntryBase {
99
- type: "custom";
100
- customType: string;
101
- data?: T;
102
- }
103
-
104
- /** Label entry for user-defined bookmarks/markers on entries. */
105
- export interface LabelEntry extends SessionEntryBase {
106
- type: "label";
107
- targetId: string;
108
- label: string | undefined;
109
- }
110
-
111
- /** Session metadata entry (e.g., user-defined display name). */
112
- export interface SessionInfoEntry extends SessionEntryBase {
113
- type: "session_info";
114
- name?: string;
115
- }
116
-
117
- /**
118
- * Custom message entry for extensions to inject messages into LLM context.
119
- * Use customType to identify your extension's entries.
120
- *
121
- * Unlike CustomEntry, this DOES participate in LLM context.
122
- * The content is converted to a user message in buildSessionContext().
123
- * Use details for extension-specific metadata (not sent to LLM).
124
- *
125
- * display controls TUI rendering:
126
- * - false: hidden entirely
127
- * - true: rendered with distinct styling (different from user messages)
128
- */
129
- export interface CustomMessageEntry<T = unknown> extends SessionEntryBase {
130
- type: "custom_message";
131
- customType: string;
132
- content: string | (TextContent | ImageContent)[];
133
- details?: T;
134
- display: boolean;
135
- }
136
-
137
- /** Session entry - has id/parentId for tree structure (returned by "read" methods in SessionManager) */
138
- export type SessionEntry =
139
- | SessionMessageEntry
140
- | ThinkingLevelChangeEntry
141
- | ModelChangeEntry
142
- | CompactionEntry
143
- | BranchSummaryEntry
144
- | CustomEntry
145
- | CustomMessageEntry
146
- | LabelEntry
147
- | SessionInfoEntry;
148
-
149
- /** Raw file entry (includes header) */
150
- export type FileEntry = SessionHeader | SessionEntry;
151
-
152
- /** Tree node for getTree() - defensive copy of session structure */
153
- export interface SessionTreeNode {
154
- entry: SessionEntry;
155
- children: SessionTreeNode[];
156
- /** Resolved label for this entry, if any */
157
- label?: string;
158
- /** Timestamp of the latest label change for this entry, if any */
159
- labelTimestamp?: string;
160
- }
161
-
162
- export interface SessionContext {
163
- messages: AgentMessage[];
164
- thinkingLevel: string;
165
- model: { provider: string; modelId: string } | null;
166
- }
167
-
168
- export interface SessionInfo {
169
- path: string;
170
- id: string;
171
- /** Working directory where the session was started. Empty string for old sessions. */
172
- cwd: string;
173
- /** User-defined display name from session_info entries. */
174
- name?: string;
175
- /** Path to the parent session (if this session was forked). */
176
- parentSessionPath?: string;
177
- created: Date;
178
- modified: Date;
179
- messageCount: number;
180
- firstMessage: string;
181
- allMessagesText: string;
182
- }
183
-
184
- export type ReadonlySessionManager = Pick<
185
- SessionManager,
186
- | "getCwd"
187
- | "getSessionDir"
188
- | "getSessionId"
189
- | "getSessionFile"
190
- | "getLeafId"
191
- | "getLeafEntry"
192
- | "getEntry"
193
- | "getLabel"
194
- | "getBranch"
195
- | "getHeader"
196
- | "getEntries"
197
- | "getTree"
198
- | "getSessionName"
199
- >;
200
-
201
- function createSessionId(): string {
202
- return uuidv7();
203
- }
204
-
205
- /** Generate a unique short ID (8 hex chars, collision-checked) */
206
- function generateId(byId: { has(id: string): boolean }): string {
207
- for (let i = 0; i < 100; i++) {
208
- const id = randomUUID().slice(0, 8);
209
- if (!byId.has(id)) return id;
210
- }
211
- // Fallback to full UUID if somehow we have collisions
212
- return randomUUID();
213
- }
214
-
215
- /** Migrate v1 → v2: add id/parentId tree structure. Mutates in place. */
216
- function migrateV1ToV2(entries: FileEntry[]): void {
217
- const ids = new Set<string>();
218
- let prevId: string | null = null;
219
-
220
- for (const entry of entries) {
221
- if (entry.type === "session") {
222
- entry.version = 2;
223
- continue;
224
- }
225
-
226
- entry.id = generateId(ids);
227
- entry.parentId = prevId;
228
- prevId = entry.id;
229
-
230
- // Convert firstKeptEntryIndex to firstKeptEntryId for compaction
231
- if (entry.type === "compaction") {
232
- const comp = entry as CompactionEntry & { firstKeptEntryIndex?: number };
233
- if (typeof comp.firstKeptEntryIndex === "number") {
234
- const targetEntry = entries[comp.firstKeptEntryIndex];
235
- if (targetEntry && targetEntry.type !== "session") {
236
- comp.firstKeptEntryId = targetEntry.id;
237
- }
238
- delete comp.firstKeptEntryIndex;
239
- }
240
- }
241
- }
242
- }
243
-
244
- /** Migrate v2 → v3: rename hookMessage role to custom. Mutates in place. */
245
- function migrateV2ToV3(entries: FileEntry[]): void {
246
- for (const entry of entries) {
247
- if (entry.type === "session") {
248
- entry.version = 3;
249
- continue;
250
- }
251
-
252
- // Update message entries with hookMessage role
253
- if (entry.type === "message") {
254
- const msgEntry = entry as SessionMessageEntry;
255
- if (msgEntry.message && (msgEntry.message as { role: string }).role === "hookMessage") {
256
- (msgEntry.message as { role: string }).role = "custom";
257
- }
258
- }
259
- }
260
- }
261
-
262
- /**
263
- * Run all necessary migrations to bring entries to current version.
264
- * Mutates entries in place. Returns true if any migration was applied.
265
- */
266
- function migrateToCurrentVersion(entries: FileEntry[]): boolean {
267
- const header = entries.find((e) => e.type === "session") as SessionHeader | undefined;
268
- const version = header?.version ?? 1;
269
-
270
- if (version >= CURRENT_SESSION_VERSION) return false;
271
-
272
- if (version < 2) migrateV1ToV2(entries);
273
- if (version < 3) migrateV2ToV3(entries);
274
-
275
- return true;
276
- }
277
-
278
- /** Exported for testing */
279
- export function migrateSessionEntries(entries: FileEntry[]): void {
280
- migrateToCurrentVersion(entries);
281
- }
282
-
283
- /** Exported for compaction.test.ts */
284
- export function parseSessionEntries(content: string): FileEntry[] {
285
- const entries: FileEntry[] = [];
286
- const lines = content.trim().split("\n");
287
-
288
- for (const line of lines) {
289
- if (!line.trim()) continue;
290
- try {
291
- const entry = JSON.parse(line) as FileEntry;
292
- entries.push(entry);
293
- } catch {
294
- // Skip malformed lines
295
- }
296
- }
297
-
298
- return entries;
299
- }
300
-
301
- export function getLatestCompactionEntry(entries: SessionEntry[]): CompactionEntry | null {
302
- for (let i = entries.length - 1; i >= 0; i--) {
303
- if (entries[i].type === "compaction") {
304
- return entries[i] as CompactionEntry;
305
- }
306
- }
307
- return null;
308
- }
309
-
310
- /**
311
- * Build the session context from entries using tree traversal.
312
- * If leafId is provided, walks from that entry to root.
313
- * Handles compaction and branch summaries along the path.
314
- */
315
- export function buildSessionContext(
316
- entries: SessionEntry[],
317
- leafId?: string | null,
318
- byId?: Map<string, SessionEntry>,
319
- ): SessionContext {
320
- // Build uuid index if not available
321
- if (!byId) {
322
- byId = new Map<string, SessionEntry>();
323
- for (const entry of entries) {
324
- byId.set(entry.id, entry);
325
- }
326
- }
327
-
328
- // Find leaf
329
- let leaf: SessionEntry | undefined;
330
- if (leafId === null) {
331
- // Explicitly null - return no messages (navigated to before first entry)
332
- return { messages: [], thinkingLevel: "off", model: null };
333
- }
334
- if (leafId) {
335
- leaf = byId.get(leafId);
336
- }
337
- if (!leaf) {
338
- // Fallback to last entry (when leafId is undefined)
339
- leaf = entries[entries.length - 1];
340
- }
341
-
342
- if (!leaf) {
343
- return { messages: [], thinkingLevel: "off", model: null };
344
- }
345
-
346
- // Walk from leaf to root, collecting path
347
- const path: SessionEntry[] = [];
348
- let current: SessionEntry | undefined = leaf;
349
- while (current) {
350
- path.unshift(current);
351
- current = current.parentId ? byId.get(current.parentId) : undefined;
352
- }
353
-
354
- // Extract settings and find compaction
355
- let thinkingLevel = "off";
356
- let model: { provider: string; modelId: string } | null = null;
357
- let compaction: CompactionEntry | null = null;
358
-
359
- for (const entry of path) {
360
- if (entry.type === "thinking_level_change") {
361
- thinkingLevel = entry.thinkingLevel;
362
- } else if (entry.type === "model_change") {
363
- model = { provider: entry.provider, modelId: entry.modelId };
364
- } else if (entry.type === "message" && entry.message.role === "assistant") {
365
- model = { provider: entry.message.provider, modelId: entry.message.model };
366
- } else if (entry.type === "compaction") {
367
- compaction = entry;
368
- }
369
- }
370
-
371
- // Build messages and collect corresponding entries
372
- // When there's a compaction, we need to:
373
- // 1. Emit summary first (entry = compaction)
374
- // 2. Emit kept messages (from firstKeptEntryId up to compaction)
375
- // 3. Emit messages after compaction
376
- const messages: AgentMessage[] = [];
377
-
378
- const appendMessage = (entry: SessionEntry) => {
379
- if (entry.type === "message") {
380
- messages.push(entry.message);
381
- } else if (entry.type === "custom_message") {
382
- messages.push(
383
- createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp),
384
- );
385
- } else if (entry.type === "branch_summary" && entry.summary) {
386
- messages.push(createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp));
387
- }
388
- };
389
-
390
- if (compaction) {
391
- // Emit summary first
392
- messages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));
393
-
394
- // Find compaction index in path
395
- const compactionIdx = path.findIndex((e) => e.type === "compaction" && e.id === compaction.id);
396
-
397
- // Emit kept messages (before compaction, starting from firstKeptEntryId)
398
- let foundFirstKept = false;
399
- for (let i = 0; i < compactionIdx; i++) {
400
- const entry = path[i];
401
- if (entry.id === compaction.firstKeptEntryId) {
402
- foundFirstKept = true;
403
- }
404
- if (foundFirstKept) {
405
- appendMessage(entry);
406
- }
407
- }
408
-
409
- // Emit messages after compaction
410
- for (let i = compactionIdx + 1; i < path.length; i++) {
411
- const entry = path[i];
412
- appendMessage(entry);
413
- }
414
- } else {
415
- // No compaction - emit all messages, handle branch summaries and custom messages
416
- for (const entry of path) {
417
- appendMessage(entry);
418
- }
419
- }
420
-
421
- return { messages, thinkingLevel, model };
422
- }
423
-
424
- /**
425
- * Compute the default session directory for a cwd.
426
- * Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.
427
- */
428
- export function getDefaultSessionDir(cwd: string, agentDir: string = getDefaultAgentDir()): string {
429
- const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
430
- const sessionDir = join(agentDir, "sessions", safePath);
431
- if (!existsSync(sessionDir)) {
432
- mkdirSync(sessionDir, { recursive: true });
433
- }
434
- return sessionDir;
435
- }
436
-
437
- /** Exported for testing */
438
- export function loadEntriesFromFile(filePath: string): FileEntry[] {
439
- if (!existsSync(filePath)) return [];
440
-
441
- const content = readFileSync(filePath, "utf8");
442
- const entries: FileEntry[] = [];
443
- const lines = content.trim().split("\n");
444
-
445
- for (const line of lines) {
446
- if (!line.trim()) continue;
447
- try {
448
- const entry = JSON.parse(line) as FileEntry;
449
- entries.push(entry);
450
- } catch {
451
- // Skip malformed lines
452
- }
453
- }
454
-
455
- // Validate session header
456
- if (entries.length === 0) return entries;
457
- const header = entries[0];
458
- if (header.type !== "session" || typeof (header as any).id !== "string") {
459
- return [];
460
- }
461
-
462
- return entries;
463
- }
464
-
465
- function isValidSessionFile(filePath: string): boolean {
466
- try {
467
- const fd = openSync(filePath, "r");
468
- const buffer = Buffer.alloc(512);
469
- const bytesRead = readSync(fd, buffer, 0, 512, 0);
470
- closeSync(fd);
471
- const firstLine = buffer.toString("utf8", 0, bytesRead).split("\n")[0];
472
- if (!firstLine) return false;
473
- const header = JSON.parse(firstLine);
474
- return header.type === "session" && typeof header.id === "string";
475
- } catch {
476
- return false;
477
- }
478
- }
479
-
480
- /** Exported for testing */
481
- export function findMostRecentSession(sessionDir: string): string | null {
482
- try {
483
- const files = readdirSync(sessionDir)
484
- .filter((f) => f.endsWith(".jsonl"))
485
- .map((f) => join(sessionDir, f))
486
- .filter(isValidSessionFile)
487
- .map((path) => ({ path, mtime: statSync(path).mtime }))
488
- .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
489
-
490
- return files[0]?.path || null;
491
- } catch {
492
- return null;
493
- }
494
- }
495
-
496
- function isMessageWithContent(message: AgentMessage): message is Message {
497
- return typeof (message as Message).role === "string" && "content" in message;
498
- }
499
-
500
- function extractTextContent(message: Message): string {
501
- const content = message.content;
502
- if (typeof content === "string") {
503
- return content;
504
- }
505
- return content
506
- .filter((block): block is TextContent => block.type === "text")
507
- .map((block) => block.text)
508
- .join(" ");
509
- }
510
-
511
- function getLastActivityTime(entries: FileEntry[]): number | undefined {
512
- let lastActivityTime: number | undefined;
513
-
514
- for (const entry of entries) {
515
- if (entry.type !== "message") continue;
516
-
517
- const message = (entry as SessionMessageEntry).message;
518
- if (!isMessageWithContent(message)) continue;
519
- if (message.role !== "user" && message.role !== "assistant") continue;
520
-
521
- const msgTimestamp = (message as { timestamp?: number }).timestamp;
522
- if (typeof msgTimestamp === "number") {
523
- lastActivityTime = Math.max(lastActivityTime ?? 0, msgTimestamp);
524
- continue;
525
- }
526
-
527
- const entryTimestamp = (entry as SessionEntryBase).timestamp;
528
- if (typeof entryTimestamp === "string") {
529
- const t = new Date(entryTimestamp).getTime();
530
- if (!Number.isNaN(t)) {
531
- lastActivityTime = Math.max(lastActivityTime ?? 0, t);
532
- }
533
- }
534
- }
535
-
536
- return lastActivityTime;
537
- }
538
-
539
- function getSessionModifiedDate(entries: FileEntry[], header: SessionHeader, statsMtime: Date): Date {
540
- const lastActivityTime = getLastActivityTime(entries);
541
- if (typeof lastActivityTime === "number" && lastActivityTime > 0) {
542
- return new Date(lastActivityTime);
543
- }
544
-
545
- const headerTime = typeof header.timestamp === "string" ? new Date(header.timestamp).getTime() : NaN;
546
- return !Number.isNaN(headerTime) ? new Date(headerTime) : statsMtime;
547
- }
548
-
549
- async function buildSessionInfo(filePath: string): Promise<SessionInfo | null> {
550
- try {
551
- const content = await readFile(filePath, "utf8");
552
- const entries: FileEntry[] = [];
553
- const lines = content.trim().split("\n");
554
-
555
- for (const line of lines) {
556
- if (!line.trim()) continue;
557
- try {
558
- entries.push(JSON.parse(line) as FileEntry);
559
- } catch {
560
- // Skip malformed lines
561
- }
562
- }
563
-
564
- if (entries.length === 0) return null;
565
- const header = entries[0];
566
- if (header.type !== "session") return null;
567
-
568
- const stats = await stat(filePath);
569
- let messageCount = 0;
570
- let firstMessage = "";
571
- const allMessages: string[] = [];
572
- let name: string | undefined;
573
-
574
- for (const entry of entries) {
575
- // Extract session name (use latest, including explicit clears)
576
- if (entry.type === "session_info") {
577
- const infoEntry = entry as SessionInfoEntry;
578
- name = infoEntry.name?.trim() || undefined;
579
- }
580
-
581
- if (entry.type !== "message") continue;
582
- messageCount++;
583
-
584
- const message = (entry as SessionMessageEntry).message;
585
- if (!isMessageWithContent(message)) continue;
586
- if (message.role !== "user" && message.role !== "assistant") continue;
587
-
588
- const textContent = extractTextContent(message);
589
- if (!textContent) continue;
590
-
591
- allMessages.push(textContent);
592
- if (!firstMessage && message.role === "user") {
593
- firstMessage = textContent;
594
- }
595
- }
596
-
597
- const cwd = typeof (header as SessionHeader).cwd === "string" ? (header as SessionHeader).cwd : "";
598
- const parentSessionPath = (header as SessionHeader).parentSession;
599
-
600
- const modified = getSessionModifiedDate(entries, header as SessionHeader, stats.mtime);
601
-
602
- return {
603
- path: filePath,
604
- id: (header as SessionHeader).id,
605
- cwd,
606
- name,
607
- parentSessionPath,
608
- created: new Date((header as SessionHeader).timestamp),
609
- modified,
610
- messageCount,
611
- firstMessage: firstMessage || "(no messages)",
612
- allMessagesText: allMessages.join(" "),
613
- };
614
- } catch {
615
- return null;
616
- }
617
- }
618
-
619
- export type SessionListProgress = (loaded: number, total: number) => void;
620
-
621
- async function listSessionsFromDir(
622
- dir: string,
623
- onProgress?: SessionListProgress,
624
- progressOffset = 0,
625
- progressTotal?: number,
626
- ): Promise<SessionInfo[]> {
627
- const sessions: SessionInfo[] = [];
628
- if (!existsSync(dir)) {
629
- return sessions;
630
- }
631
-
632
- try {
633
- const dirEntries = await readdir(dir);
634
- const files = dirEntries.filter((f) => f.endsWith(".jsonl")).map((f) => join(dir, f));
635
- const total = progressTotal ?? files.length;
636
-
637
- let loaded = 0;
638
- const results = await Promise.all(
639
- files.map(async (file) => {
640
- const info = await buildSessionInfo(file);
641
- loaded++;
642
- onProgress?.(progressOffset + loaded, total);
643
- return info;
644
- }),
645
- );
646
- for (const info of results) {
647
- if (info) {
648
- sessions.push(info);
649
- }
650
- }
651
- } catch {
652
- // Return empty list on error
653
- }
654
-
655
- return sessions;
656
- }
657
-
658
- /**
659
- * Manages conversation sessions as append-only trees stored in JSONL files.
660
- *
661
- * Each session entry has an id and parentId forming a tree structure. The "leaf"
662
- * pointer tracks the current position. Appending creates a child of the current leaf.
663
- * Branching moves the leaf to an earlier entry, allowing new branches without
664
- * modifying history.
665
- *
666
- * Use buildSessionContext() to get the resolved message list for the LLM, which
667
- * handles compaction summaries and follows the path from root to current leaf.
668
- */
669
- export class SessionManager {
670
- private sessionId: string = "";
671
- private sessionFile: string | undefined;
672
- private sessionDir: string;
673
- private cwd: string;
674
- private persist: boolean;
675
- private flushed: boolean = false;
676
- private fileEntries: FileEntry[] = [];
677
- private byId: Map<string, SessionEntry> = new Map();
678
- private labelsById: Map<string, string> = new Map();
679
- private labelTimestampsById: Map<string, string> = new Map();
680
- private leafId: string | null = null;
681
-
682
- private constructor(cwd: string, sessionDir: string, sessionFile: string | undefined, persist: boolean) {
683
- this.cwd = cwd;
684
- this.sessionDir = sessionDir;
685
- this.persist = persist;
686
- if (persist && sessionDir && !existsSync(sessionDir)) {
687
- mkdirSync(sessionDir, { recursive: true });
688
- }
689
-
690
- if (sessionFile) {
691
- this.setSessionFile(sessionFile);
692
- } else {
693
- this.newSession();
694
- }
695
- }
696
-
697
- /** Switch to a different session file (used for resume and branching) */
698
- setSessionFile(sessionFile: string): void {
699
- this.sessionFile = resolve(sessionFile);
700
- if (existsSync(this.sessionFile)) {
701
- this.fileEntries = loadEntriesFromFile(this.sessionFile);
702
-
703
- // If file was empty or corrupted (no valid header), truncate and start fresh
704
- // to avoid appending messages without a session header (which breaks the session)
705
- if (this.fileEntries.length === 0) {
706
- const explicitPath = this.sessionFile;
707
- this.newSession();
708
- this.sessionFile = explicitPath;
709
- this._rewriteFile();
710
- this.flushed = true;
711
- return;
712
- }
713
-
714
- const header = this.fileEntries.find((e) => e.type === "session") as SessionHeader | undefined;
715
- this.sessionId = header?.id ?? createSessionId();
716
-
717
- if (migrateToCurrentVersion(this.fileEntries)) {
718
- this._rewriteFile();
719
- }
720
-
721
- this._buildIndex();
722
- this.flushed = true;
723
- } else {
724
- const explicitPath = this.sessionFile;
725
- this.newSession();
726
- this.sessionFile = explicitPath; // preserve explicit path from --session flag
727
- }
728
- }
729
-
730
- newSession(options?: NewSessionOptions): string | undefined {
731
- this.sessionId = options?.id ?? createSessionId();
732
- const timestamp = new Date().toISOString();
733
- const header: SessionHeader = {
734
- type: "session",
735
- version: CURRENT_SESSION_VERSION,
736
- id: this.sessionId,
737
- timestamp,
738
- cwd: this.cwd,
739
- parentSession: options?.parentSession,
740
- };
741
- this.fileEntries = [header];
742
- this.byId.clear();
743
- this.labelsById.clear();
744
- this.leafId = null;
745
- this.flushed = false;
746
-
747
- if (this.persist) {
748
- const fileTimestamp = timestamp.replace(/[:.]/g, "-");
749
- this.sessionFile = join(this.getSessionDir(), `${fileTimestamp}_${this.sessionId}.jsonl`);
750
- }
751
- return this.sessionFile;
752
- }
753
-
754
- private _buildIndex(): void {
755
- this.byId.clear();
756
- this.labelsById.clear();
757
- this.labelTimestampsById.clear();
758
- this.leafId = null;
759
- for (const entry of this.fileEntries) {
760
- if (entry.type === "session") continue;
761
- this.byId.set(entry.id, entry);
762
- this.leafId = entry.id;
763
- if (entry.type === "label") {
764
- if (entry.label) {
765
- this.labelsById.set(entry.targetId, entry.label);
766
- this.labelTimestampsById.set(entry.targetId, entry.timestamp);
767
- } else {
768
- this.labelsById.delete(entry.targetId);
769
- this.labelTimestampsById.delete(entry.targetId);
770
- }
771
- }
772
- }
773
- }
774
-
775
- private _rewriteFile(): void {
776
- if (!this.persist || !this.sessionFile) return;
777
- const content = `${this.fileEntries.map((e) => JSON.stringify(e)).join("\n")}\n`;
778
- writeFileSync(this.sessionFile, content);
779
- }
780
-
781
- isPersisted(): boolean {
782
- return this.persist;
783
- }
784
-
785
- getCwd(): string {
786
- return this.cwd;
787
- }
788
-
789
- getSessionDir(): string {
790
- return this.sessionDir;
791
- }
792
-
793
- getSessionId(): string {
794
- return this.sessionId;
795
- }
796
-
797
- getSessionFile(): string | undefined {
798
- return this.sessionFile;
799
- }
800
-
801
- _persist(entry: SessionEntry): void {
802
- if (!this.persist || !this.sessionFile) return;
803
-
804
- const hasAssistant = this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant");
805
- if (!hasAssistant) {
806
- // Mark as not flushed so when assistant arrives, all entries get written
807
- this.flushed = false;
808
- return;
809
- }
810
-
811
- if (!this.flushed) {
812
- for (const e of this.fileEntries) {
813
- appendFileSync(this.sessionFile, `${JSON.stringify(e)}\n`);
814
- }
815
- this.flushed = true;
816
- } else {
817
- appendFileSync(this.sessionFile, `${JSON.stringify(entry)}\n`);
818
- }
819
- }
820
-
821
- private _appendEntry(entry: SessionEntry): void {
822
- this.fileEntries.push(entry);
823
- this.byId.set(entry.id, entry);
824
- this.leafId = entry.id;
825
- this._persist(entry);
826
- }
827
-
828
- /** Append a message as child of current leaf, then advance leaf. Returns entry id.
829
- * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.
830
- * Reason: we want these to be top-level entries in the session, not message session entries,
831
- * so it is easier to find them.
832
- * These need to be appended via appendCompaction() and appendBranchSummary() methods.
833
- */
834
- appendMessage(message: Message | CustomMessage | BashExecutionMessage): string {
835
- const entry: SessionMessageEntry = {
836
- type: "message",
837
- id: generateId(this.byId),
838
- parentId: this.leafId,
839
- timestamp: new Date().toISOString(),
840
- message,
841
- };
842
- this._appendEntry(entry);
843
- return entry.id;
844
- }
845
-
846
- /** Append a thinking level change as child of current leaf, then advance leaf. Returns entry id. */
847
- appendThinkingLevelChange(thinkingLevel: string): string {
848
- const entry: ThinkingLevelChangeEntry = {
849
- type: "thinking_level_change",
850
- id: generateId(this.byId),
851
- parentId: this.leafId,
852
- timestamp: new Date().toISOString(),
853
- thinkingLevel,
854
- };
855
- this._appendEntry(entry);
856
- return entry.id;
857
- }
858
-
859
- /** Append a model change as child of current leaf, then advance leaf. Returns entry id. */
860
- appendModelChange(provider: string, modelId: string): string {
861
- const entry: ModelChangeEntry = {
862
- type: "model_change",
863
- id: generateId(this.byId),
864
- parentId: this.leafId,
865
- timestamp: new Date().toISOString(),
866
- provider,
867
- modelId,
868
- };
869
- this._appendEntry(entry);
870
- return entry.id;
871
- }
872
-
873
- /** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */
874
- appendCompaction<T = unknown>(
875
- summary: string,
876
- firstKeptEntryId: string,
877
- tokensBefore: number,
878
- details?: T,
879
- fromHook?: boolean,
880
- ): string {
881
- const entry: CompactionEntry<T> = {
882
- type: "compaction",
883
- id: generateId(this.byId),
884
- parentId: this.leafId,
885
- timestamp: new Date().toISOString(),
886
- summary,
887
- firstKeptEntryId,
888
- tokensBefore,
889
- details,
890
- fromHook,
891
- };
892
- this._appendEntry(entry);
893
- return entry.id;
894
- }
895
-
896
- /** Append a custom entry (for extensions) as child of current leaf, then advance leaf. Returns entry id. */
897
- appendCustomEntry(customType: string, data?: unknown): string {
898
- const entry: CustomEntry = {
899
- type: "custom",
900
- customType,
901
- data,
902
- id: generateId(this.byId),
903
- parentId: this.leafId,
904
- timestamp: new Date().toISOString(),
905
- };
906
- this._appendEntry(entry);
907
- return entry.id;
908
- }
909
-
910
- /** Append a session info entry (e.g., display name). Returns entry id. */
911
- appendSessionInfo(name: string): string {
912
- const entry: SessionInfoEntry = {
913
- type: "session_info",
914
- id: generateId(this.byId),
915
- parentId: this.leafId,
916
- timestamp: new Date().toISOString(),
917
- name: name.trim(),
918
- };
919
- this._appendEntry(entry);
920
- return entry.id;
921
- }
922
-
923
- /** Get the current session name from the latest session_info entry, if any. */
924
- getSessionName(): string | undefined {
925
- // Walk entries in reverse to find the latest session_info entry.
926
- // Empty names explicitly clear the session title.
927
- const entries = this.getEntries();
928
- for (let i = entries.length - 1; i >= 0; i--) {
929
- const entry = entries[i];
930
- if (entry.type === "session_info") {
931
- return entry.name?.trim() || undefined;
932
- }
933
- }
934
- return undefined;
935
- }
936
-
937
- /**
938
- * Append a custom message entry (for extensions) that participates in LLM context.
939
- * @param customType Extension identifier for filtering on reload
940
- * @param content Message content (string or TextContent/ImageContent array)
941
- * @param display Whether to show in TUI (true = styled display, false = hidden)
942
- * @param details Optional extension-specific metadata (not sent to LLM)
943
- * @returns Entry id
944
- */
945
- appendCustomMessageEntry<T = unknown>(
946
- customType: string,
947
- content: string | (TextContent | ImageContent)[],
948
- display: boolean,
949
- details?: T,
950
- ): string {
951
- const entry: CustomMessageEntry<T> = {
952
- type: "custom_message",
953
- customType,
954
- content,
955
- display,
956
- details,
957
- id: generateId(this.byId),
958
- parentId: this.leafId,
959
- timestamp: new Date().toISOString(),
960
- };
961
- this._appendEntry(entry);
962
- return entry.id;
963
- }
964
-
965
- // =========================================================================
966
- // Tree Traversal
967
- // =========================================================================
968
-
969
- getLeafId(): string | null {
970
- return this.leafId;
971
- }
972
-
973
- getLeafEntry(): SessionEntry | undefined {
974
- return this.leafId ? this.byId.get(this.leafId) : undefined;
975
- }
976
-
977
- getEntry(id: string): SessionEntry | undefined {
978
- return this.byId.get(id);
979
- }
980
-
981
- /**
982
- * Get all direct children of an entry.
983
- */
984
- getChildren(parentId: string): SessionEntry[] {
985
- const children: SessionEntry[] = [];
986
- for (const entry of this.byId.values()) {
987
- if (entry.parentId === parentId) {
988
- children.push(entry);
989
- }
990
- }
991
- return children;
992
- }
993
-
994
- /**
995
- * Get the label for an entry, if any.
996
- */
997
- getLabel(id: string): string | undefined {
998
- return this.labelsById.get(id);
999
- }
1000
-
1001
- /**
1002
- * Set or clear a label on an entry.
1003
- * Labels are user-defined markers for bookmarking/navigation.
1004
- * Pass undefined or empty string to clear the label.
1005
- */
1006
- appendLabelChange(targetId: string, label: string | undefined): string {
1007
- if (!this.byId.has(targetId)) {
1008
- throw new Error(`Entry ${targetId} not found`);
1009
- }
1010
- const entry: LabelEntry = {
1011
- type: "label",
1012
- id: generateId(this.byId),
1013
- parentId: this.leafId,
1014
- timestamp: new Date().toISOString(),
1015
- targetId,
1016
- label,
1017
- };
1018
- this._appendEntry(entry);
1019
- if (label) {
1020
- this.labelsById.set(targetId, label);
1021
- this.labelTimestampsById.set(targetId, entry.timestamp);
1022
- } else {
1023
- this.labelsById.delete(targetId);
1024
- this.labelTimestampsById.delete(targetId);
1025
- }
1026
- return entry.id;
1027
- }
1028
-
1029
- /**
1030
- * Walk from entry to root, returning all entries in path order.
1031
- * Includes all entry types (messages, compaction, model changes, etc.).
1032
- * Use buildSessionContext() to get the resolved messages for the LLM.
1033
- */
1034
- getBranch(fromId?: string): SessionEntry[] {
1035
- const path: SessionEntry[] = [];
1036
- const startId = fromId ?? this.leafId;
1037
- let current = startId ? this.byId.get(startId) : undefined;
1038
- while (current) {
1039
- path.unshift(current);
1040
- current = current.parentId ? this.byId.get(current.parentId) : undefined;
1041
- }
1042
- return path;
1043
- }
1044
-
1045
- /**
1046
- * Build the session context (what gets sent to the LLM).
1047
- * Uses tree traversal from current leaf.
1048
- */
1049
- buildSessionContext(): SessionContext {
1050
- return buildSessionContext(this.getEntries(), this.leafId, this.byId);
1051
- }
1052
-
1053
- /**
1054
- * Get session header.
1055
- */
1056
- getHeader(): SessionHeader | null {
1057
- const h = this.fileEntries.find((e) => e.type === "session");
1058
- return h ? (h as SessionHeader) : null;
1059
- }
1060
-
1061
- /**
1062
- * Get all session entries (excludes header). Returns a shallow copy.
1063
- * The session is append-only: use appendXXX() to add entries, branch() to
1064
- * change the leaf pointer. Entries cannot be modified or deleted.
1065
- */
1066
- getEntries(): SessionEntry[] {
1067
- return this.fileEntries.filter((e): e is SessionEntry => e.type !== "session");
1068
- }
1069
-
1070
- /**
1071
- * Get the session as a tree structure. Returns a shallow defensive copy of all entries.
1072
- * A well-formed session has exactly one root (first entry with parentId === null).
1073
- * Orphaned entries (broken parent chain) are also returned as roots.
1074
- */
1075
- getTree(): SessionTreeNode[] {
1076
- const entries = this.getEntries();
1077
- const nodeMap = new Map<string, SessionTreeNode>();
1078
- const roots: SessionTreeNode[] = [];
1079
-
1080
- // Create nodes with resolved labels
1081
- for (const entry of entries) {
1082
- const label = this.labelsById.get(entry.id);
1083
- const labelTimestamp = this.labelTimestampsById.get(entry.id);
1084
- nodeMap.set(entry.id, { entry, children: [], label, labelTimestamp });
1085
- }
1086
-
1087
- // Build tree
1088
- for (const entry of entries) {
1089
- const node = nodeMap.get(entry.id)!;
1090
- if (entry.parentId === null || entry.parentId === entry.id) {
1091
- roots.push(node);
1092
- } else {
1093
- const parent = nodeMap.get(entry.parentId);
1094
- if (parent) {
1095
- parent.children.push(node);
1096
- } else {
1097
- // Orphan - treat as root
1098
- roots.push(node);
1099
- }
1100
- }
1101
- }
1102
-
1103
- // Sort children by timestamp (oldest first, newest at bottom)
1104
- // Use iterative approach to avoid stack overflow on deep trees
1105
- const stack: SessionTreeNode[] = [...roots];
1106
- while (stack.length > 0) {
1107
- const node = stack.pop()!;
1108
- node.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());
1109
- stack.push(...node.children);
1110
- }
1111
-
1112
- return roots;
1113
- }
1114
-
1115
- // =========================================================================
1116
- // Branching
1117
- // =========================================================================
1118
-
1119
- /**
1120
- * Start a new branch from an earlier entry.
1121
- * Moves the leaf pointer to the specified entry. The next appendXXX() call
1122
- * will create a child of that entry, forming a new branch. Existing entries
1123
- * are not modified or deleted.
1124
- */
1125
- branch(branchFromId: string): void {
1126
- if (!this.byId.has(branchFromId)) {
1127
- throw new Error(`Entry ${branchFromId} not found`);
1128
- }
1129
- this.leafId = branchFromId;
1130
- }
1131
-
1132
- /**
1133
- * Reset the leaf pointer to null (before any entries).
1134
- * The next appendXXX() call will create a new root entry (parentId = null).
1135
- * Use this when navigating to re-edit the first user message.
1136
- */
1137
- resetLeaf(): void {
1138
- this.leafId = null;
1139
- }
1140
-
1141
- /**
1142
- * Start a new branch with a summary of the abandoned path.
1143
- * Same as branch(), but also appends a branch_summary entry that captures
1144
- * context from the abandoned conversation path.
1145
- */
1146
- branchWithSummary(branchFromId: string | null, summary: string, details?: unknown, fromHook?: boolean): string {
1147
- if (branchFromId !== null && !this.byId.has(branchFromId)) {
1148
- throw new Error(`Entry ${branchFromId} not found`);
1149
- }
1150
- this.leafId = branchFromId;
1151
- const entry: BranchSummaryEntry = {
1152
- type: "branch_summary",
1153
- id: generateId(this.byId),
1154
- parentId: branchFromId,
1155
- timestamp: new Date().toISOString(),
1156
- fromId: branchFromId ?? "root",
1157
- summary,
1158
- details,
1159
- fromHook,
1160
- };
1161
- this._appendEntry(entry);
1162
- return entry.id;
1163
- }
1164
-
1165
- /**
1166
- * Create a new session file containing only the path from root to the specified leaf.
1167
- * Useful for extracting a single conversation path from a branched session.
1168
- * Returns the new session file path, or undefined if not persisting.
1169
- */
1170
- createBranchedSession(leafId: string): string | undefined {
1171
- const previousSessionFile = this.sessionFile;
1172
- const path = this.getBranch(leafId);
1173
- if (path.length === 0) {
1174
- throw new Error(`Entry ${leafId} not found`);
1175
- }
1176
-
1177
- // Filter out LabelEntry from path - we'll recreate them from the resolved map
1178
- const pathWithoutLabels = path.filter((e) => e.type !== "label");
1179
-
1180
- const newSessionId = createSessionId();
1181
- const timestamp = new Date().toISOString();
1182
- const fileTimestamp = timestamp.replace(/[:.]/g, "-");
1183
- const newSessionFile = join(this.getSessionDir(), `${fileTimestamp}_${newSessionId}.jsonl`);
1184
-
1185
- const header: SessionHeader = {
1186
- type: "session",
1187
- version: CURRENT_SESSION_VERSION,
1188
- id: newSessionId,
1189
- timestamp,
1190
- cwd: this.cwd,
1191
- parentSession: this.persist ? previousSessionFile : undefined,
1192
- };
1193
-
1194
- // Collect labels for entries in the path
1195
- const pathEntryIds = new Set(pathWithoutLabels.map((e) => e.id));
1196
- const labelsToWrite: Array<{ targetId: string; label: string; timestamp: string }> = [];
1197
- for (const [targetId, label] of this.labelsById) {
1198
- if (pathEntryIds.has(targetId)) {
1199
- labelsToWrite.push({ targetId, label, timestamp: this.labelTimestampsById.get(targetId)! });
1200
- }
1201
- }
1202
-
1203
- if (this.persist) {
1204
- // Build label entries
1205
- const lastEntryId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;
1206
- let parentId = lastEntryId;
1207
- const labelEntries: LabelEntry[] = [];
1208
- for (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {
1209
- const labelEntry: LabelEntry = {
1210
- type: "label",
1211
- id: generateId(new Set(pathEntryIds)),
1212
- parentId,
1213
- timestamp: labelTimestamp,
1214
- targetId,
1215
- label,
1216
- };
1217
- pathEntryIds.add(labelEntry.id);
1218
- labelEntries.push(labelEntry);
1219
- parentId = labelEntry.id;
1220
- }
1221
-
1222
- this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];
1223
- this.sessionId = newSessionId;
1224
- this.sessionFile = newSessionFile;
1225
- this._buildIndex();
1226
-
1227
- // Only write the file now if it contains an assistant message.
1228
- // Otherwise defer to _persist(), which creates the file on the
1229
- // first assistant response, matching the newSession() contract
1230
- // and avoiding the duplicate-header bug when _persist()'s
1231
- // no-assistant guard later resets flushed to false.
1232
- const hasAssistant = this.fileEntries.some((e) => e.type === "message" && e.message.role === "assistant");
1233
- if (hasAssistant) {
1234
- this._rewriteFile();
1235
- this.flushed = true;
1236
- } else {
1237
- this.flushed = false;
1238
- }
1239
-
1240
- return newSessionFile;
1241
- }
1242
-
1243
- // In-memory mode: replace current session with the path + labels
1244
- const labelEntries: LabelEntry[] = [];
1245
- let parentId = pathWithoutLabels[pathWithoutLabels.length - 1]?.id || null;
1246
- for (const { targetId, label, timestamp: labelTimestamp } of labelsToWrite) {
1247
- const labelEntry: LabelEntry = {
1248
- type: "label",
1249
- id: generateId(new Set([...pathEntryIds, ...labelEntries.map((e) => e.id)])),
1250
- parentId,
1251
- timestamp: labelTimestamp,
1252
- targetId,
1253
- label,
1254
- };
1255
- labelEntries.push(labelEntry);
1256
- parentId = labelEntry.id;
1257
- }
1258
- this.fileEntries = [header, ...pathWithoutLabels, ...labelEntries];
1259
- this.sessionId = newSessionId;
1260
- this._buildIndex();
1261
- return undefined;
1262
- }
1263
-
1264
- /**
1265
- * Create a new session.
1266
- * @param cwd Working directory (stored in session header)
1267
- * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
1268
- */
1269
- static create(cwd: string, sessionDir?: string): SessionManager {
1270
- const dir = sessionDir ?? getDefaultSessionDir(cwd);
1271
- return new SessionManager(cwd, dir, undefined, true);
1272
- }
1273
-
1274
- /**
1275
- * Open a specific session file.
1276
- * @param path Path to session file
1277
- * @param sessionDir Optional session directory for /new or /branch. If omitted, derives from file's parent.
1278
- * @param cwdOverride Optional cwd override instead of the session header cwd.
1279
- */
1280
- static open(path: string, sessionDir?: string, cwdOverride?: string): SessionManager {
1281
- // Extract cwd from session header if possible, otherwise use process.cwd()
1282
- const entries = loadEntriesFromFile(path);
1283
- const header = entries.find((e) => e.type === "session") as SessionHeader | undefined;
1284
- const cwd = cwdOverride ?? header?.cwd ?? process.cwd();
1285
- // If no sessionDir provided, derive from file's parent directory
1286
- const dir = sessionDir ?? resolve(path, "..");
1287
- return new SessionManager(cwd, dir, path, true);
1288
- }
1289
-
1290
- /**
1291
- * Continue the most recent session, or create new if none.
1292
- * @param cwd Working directory
1293
- * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
1294
- */
1295
- static continueRecent(cwd: string, sessionDir?: string): SessionManager {
1296
- const dir = sessionDir ?? getDefaultSessionDir(cwd);
1297
- const mostRecent = findMostRecentSession(dir);
1298
- if (mostRecent) {
1299
- return new SessionManager(cwd, dir, mostRecent, true);
1300
- }
1301
- return new SessionManager(cwd, dir, undefined, true);
1302
- }
1303
-
1304
- /** Create an in-memory session (no file persistence) */
1305
- static inMemory(cwd: string = process.cwd()): SessionManager {
1306
- return new SessionManager(cwd, "", undefined, false);
1307
- }
1308
-
1309
- /**
1310
- * Fork a session from another project directory into the current project.
1311
- * Creates a new session in the target cwd with the full history from the source session.
1312
- * @param sourcePath Path to the source session file
1313
- * @param targetCwd Target working directory (where the new session will be stored)
1314
- * @param sessionDir Optional session directory. If omitted, uses default for targetCwd.
1315
- */
1316
- static forkFrom(sourcePath: string, targetCwd: string, sessionDir?: string): SessionManager {
1317
- const sourceEntries = loadEntriesFromFile(sourcePath);
1318
- if (sourceEntries.length === 0) {
1319
- throw new Error(`Cannot fork: source session file is empty or invalid: ${sourcePath}`);
1320
- }
1321
-
1322
- const sourceHeader = sourceEntries.find((e) => e.type === "session") as SessionHeader | undefined;
1323
- if (!sourceHeader) {
1324
- throw new Error(`Cannot fork: source session has no header: ${sourcePath}`);
1325
- }
1326
-
1327
- const dir = sessionDir ?? getDefaultSessionDir(targetCwd);
1328
- if (!existsSync(dir)) {
1329
- mkdirSync(dir, { recursive: true });
1330
- }
1331
-
1332
- // Create new session file with new ID but forked content
1333
- const newSessionId = createSessionId();
1334
- const timestamp = new Date().toISOString();
1335
- const fileTimestamp = timestamp.replace(/[:.]/g, "-");
1336
- const newSessionFile = join(dir, `${fileTimestamp}_${newSessionId}.jsonl`);
1337
-
1338
- // Write new header pointing to source as parent, with updated cwd
1339
- const newHeader: SessionHeader = {
1340
- type: "session",
1341
- version: CURRENT_SESSION_VERSION,
1342
- id: newSessionId,
1343
- timestamp,
1344
- cwd: targetCwd,
1345
- parentSession: sourcePath,
1346
- };
1347
- appendFileSync(newSessionFile, `${JSON.stringify(newHeader)}\n`);
1348
-
1349
- // Copy all non-header entries from source
1350
- for (const entry of sourceEntries) {
1351
- if (entry.type !== "session") {
1352
- appendFileSync(newSessionFile, `${JSON.stringify(entry)}\n`);
1353
- }
1354
- }
1355
-
1356
- return new SessionManager(targetCwd, dir, newSessionFile, true);
1357
- }
1358
-
1359
- /**
1360
- * List all sessions for a directory.
1361
- * @param cwd Working directory (used to compute default session directory)
1362
- * @param sessionDir Optional session directory. If omitted, uses default (~/.pi/agent/sessions/<encoded-cwd>/).
1363
- * @param onProgress Optional callback for progress updates (loaded, total)
1364
- */
1365
- static async list(cwd: string, sessionDir?: string, onProgress?: SessionListProgress): Promise<SessionInfo[]> {
1366
- const dir = sessionDir ?? getDefaultSessionDir(cwd);
1367
- const sessions = await listSessionsFromDir(dir, onProgress);
1368
- sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
1369
- return sessions;
1370
- }
1371
-
1372
- /**
1373
- * List all sessions across all project directories.
1374
- * @param onProgress Optional callback for progress updates (loaded, total)
1375
- */
1376
- static async listAll(onProgress?: SessionListProgress): Promise<SessionInfo[]> {
1377
- const sessionsDir = getSessionsDir();
1378
-
1379
- try {
1380
- if (!existsSync(sessionsDir)) {
1381
- return [];
1382
- }
1383
- const entries = await readdir(sessionsDir, { withFileTypes: true });
1384
- const dirs = entries.filter((e) => e.isDirectory()).map((e) => join(sessionsDir, e.name));
1385
-
1386
- // Count total files first for accurate progress
1387
- let totalFiles = 0;
1388
- const dirFiles: string[][] = [];
1389
- for (const dir of dirs) {
1390
- try {
1391
- const files = (await readdir(dir)).filter((f) => f.endsWith(".jsonl"));
1392
- dirFiles.push(files.map((f) => join(dir, f)));
1393
- totalFiles += files.length;
1394
- } catch {
1395
- dirFiles.push([]);
1396
- }
1397
- }
1398
-
1399
- // Process all files with progress tracking
1400
- let loaded = 0;
1401
- const sessions: SessionInfo[] = [];
1402
- const allFiles = dirFiles.flat();
1403
-
1404
- const results = await Promise.all(
1405
- allFiles.map(async (file) => {
1406
- const info = await buildSessionInfo(file);
1407
- loaded++;
1408
- onProgress?.(loaded, totalFiles);
1409
- return info;
1410
- }),
1411
- );
1412
-
1413
- for (const info of results) {
1414
- if (info) {
1415
- sessions.push(info);
1416
- }
1417
- }
1418
-
1419
- sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
1420
- return sessions;
1421
- } catch {
1422
- return [];
1423
- }
1424
- }
1425
- }