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,1770 +0,0 @@
1
- (function() {
2
- 'use strict';
3
-
4
- // ============================================================
5
- // DATA LOADING
6
- // ============================================================
7
-
8
- const base64 = document.getElementById('session-data').textContent;
9
- const binary = atob(base64);
10
- const bytes = new Uint8Array(binary.length);
11
- for (let i = 0; i < binary.length; i++) {
12
- bytes[i] = binary.charCodeAt(i);
13
- }
14
- const data = JSON.parse(new TextDecoder('utf-8').decode(bytes));
15
- const { header, entries, leafId: defaultLeafId, systemPrompt, tools, renderedTools } = data;
16
-
17
- // ============================================================
18
- // URL PARAMETER HANDLING
19
- // ============================================================
20
-
21
- // Parse URL parameters for deep linking: leafId and targetId
22
- // Check for injected params (when loaded in iframe via srcdoc) or use window.location
23
- const injectedParams = document.querySelector('meta[name="pi-url-params"]');
24
- const searchString = injectedParams ? injectedParams.content : window.location.search.substring(1);
25
- const urlParams = new URLSearchParams(searchString);
26
- const urlLeafId = urlParams.get('leafId');
27
- const urlTargetId = urlParams.get('targetId');
28
- // Use URL leafId if provided, otherwise fall back to session default
29
- const leafId = urlLeafId || defaultLeafId;
30
-
31
- // ============================================================
32
- // DATA STRUCTURES
33
- // ============================================================
34
-
35
- // Entry lookup by ID
36
- const byId = new Map();
37
- for (const entry of entries) {
38
- byId.set(entry.id, entry);
39
- }
40
-
41
- // Tool call lookup (toolCallId -> {name, arguments})
42
- const toolCallMap = new Map();
43
- for (const entry of entries) {
44
- if (entry.type === 'message' && entry.message.role === 'assistant') {
45
- const content = entry.message.content;
46
- if (Array.isArray(content)) {
47
- for (const block of content) {
48
- if (block.type === 'toolCall') {
49
- toolCallMap.set(block.id, { name: block.name, arguments: block.arguments });
50
- }
51
- }
52
- }
53
- }
54
- }
55
-
56
- // Label lookup (entryId -> label string)
57
- // Labels are stored in 'label' entries that reference their target via targetId
58
- const labelMap = new Map();
59
- for (const entry of entries) {
60
- if (entry.type === 'label' && entry.targetId && entry.label) {
61
- labelMap.set(entry.targetId, entry.label);
62
- }
63
- }
64
-
65
- // ============================================================
66
- // TREE DATA PREPARATION (no DOM, pure data)
67
- // ============================================================
68
-
69
- /**
70
- * Build tree structure from flat entries.
71
- * Returns array of root nodes, each with { entry, children, label }.
72
- */
73
- function buildTree() {
74
- const nodeMap = new Map();
75
- const roots = [];
76
-
77
- // Create nodes
78
- for (const entry of entries) {
79
- nodeMap.set(entry.id, {
80
- entry,
81
- children: [],
82
- label: labelMap.get(entry.id)
83
- });
84
- }
85
-
86
- // Build parent-child relationships
87
- for (const entry of entries) {
88
- const node = nodeMap.get(entry.id);
89
- if (entry.parentId === null || entry.parentId === undefined || entry.parentId === entry.id) {
90
- roots.push(node);
91
- } else {
92
- const parent = nodeMap.get(entry.parentId);
93
- if (parent) {
94
- parent.children.push(node);
95
- } else {
96
- roots.push(node);
97
- }
98
- }
99
- }
100
-
101
- // Sort children by timestamp
102
- function sortChildren(node) {
103
- node.children.sort((a, b) =>
104
- new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime()
105
- );
106
- node.children.forEach(sortChildren);
107
- }
108
- roots.forEach(sortChildren);
109
-
110
- return roots;
111
- }
112
-
113
- /**
114
- * Build set of entry IDs on path from root to target.
115
- */
116
- function buildActivePathIds(targetId) {
117
- const ids = new Set();
118
- let current = byId.get(targetId);
119
- while (current) {
120
- ids.add(current.id);
121
- // Stop if no parent or self-referencing (root)
122
- if (!current.parentId || current.parentId === current.id) {
123
- break;
124
- }
125
- current = byId.get(current.parentId);
126
- }
127
- return ids;
128
- }
129
-
130
- /**
131
- * Get array of entries from root to target (the conversation path).
132
- */
133
- function getPath(targetId) {
134
- const path = [];
135
- let current = byId.get(targetId);
136
- while (current) {
137
- path.unshift(current);
138
- // Stop if no parent or self-referencing (root)
139
- if (!current.parentId || current.parentId === current.id) {
140
- break;
141
- }
142
- current = byId.get(current.parentId);
143
- }
144
- return path;
145
- }
146
-
147
- // Tree node lookup for finding leaves
148
- let treeNodeMap = null;
149
-
150
- /**
151
- * Find the newest leaf node reachable from a given node.
152
- * This allows clicking any node in a branch to show the full branch.
153
- * Children are sorted by timestamp, so the newest is always last.
154
- */
155
- function findNewestLeaf(nodeId) {
156
- // Build tree node map lazily
157
- if (!treeNodeMap) {
158
- treeNodeMap = new Map();
159
- const tree = buildTree();
160
- function mapNodes(node) {
161
- treeNodeMap.set(node.entry.id, node);
162
- node.children.forEach(mapNodes);
163
- }
164
- tree.forEach(mapNodes);
165
- }
166
-
167
- const node = treeNodeMap.get(nodeId);
168
- if (!node) return nodeId;
169
-
170
- // Follow the newest (last) child at each level
171
- let current = node;
172
- while (current.children.length > 0) {
173
- current = current.children[current.children.length - 1];
174
- }
175
- return current.entry.id;
176
- }
177
-
178
- /**
179
- * Flatten tree into list with indentation and connector info.
180
- * Returns array of { node, indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots }.
181
- * Matches tree-selector.ts logic exactly.
182
- */
183
- function flattenTree(roots, activePathIds) {
184
- const result = [];
185
- const multipleRoots = roots.length > 1;
186
-
187
- // Mark which subtrees contain the active leaf
188
- const containsActive = new Map();
189
- function markActive(node) {
190
- let has = activePathIds.has(node.entry.id);
191
- for (const child of node.children) {
192
- if (markActive(child)) has = true;
193
- }
194
- containsActive.set(node, has);
195
- return has;
196
- }
197
- roots.forEach(markActive);
198
-
199
- // Stack: [node, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild]
200
- const stack = [];
201
-
202
- // Add roots (prioritize branch containing active leaf)
203
- const orderedRoots = [...roots].sort((a, b) =>
204
- Number(containsActive.get(b)) - Number(containsActive.get(a))
205
- );
206
- for (let i = orderedRoots.length - 1; i >= 0; i--) {
207
- const isLast = i === orderedRoots.length - 1;
208
- stack.push([orderedRoots[i], multipleRoots ? 1 : 0, multipleRoots, multipleRoots, isLast, [], multipleRoots]);
209
- }
210
-
211
- while (stack.length > 0) {
212
- const [node, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild] = stack.pop();
213
-
214
- result.push({ node, indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots });
215
-
216
- const children = node.children;
217
- const multipleChildren = children.length > 1;
218
-
219
- // Order children (active branch first)
220
- const orderedChildren = [...children].sort((a, b) =>
221
- Number(containsActive.get(b)) - Number(containsActive.get(a))
222
- );
223
-
224
- // Calculate child indent (matches tree-selector.ts)
225
- let childIndent;
226
- if (multipleChildren) {
227
- // Parent branches: children get +1
228
- childIndent = indent + 1;
229
- } else if (justBranched && indent > 0) {
230
- // First generation after a branch: +1 for visual grouping
231
- childIndent = indent + 1;
232
- } else {
233
- // Single-child chain: stay flat
234
- childIndent = indent;
235
- }
236
-
237
- // Build gutters for children
238
- const connectorDisplayed = showConnector && !isVirtualRootChild;
239
- const currentDisplayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
240
- const connectorPosition = Math.max(0, currentDisplayIndent - 1);
241
- const childGutters = connectorDisplayed
242
- ? [...gutters, { position: connectorPosition, show: !isLast }]
243
- : gutters;
244
-
245
- // Add children in reverse order for stack
246
- for (let i = orderedChildren.length - 1; i >= 0; i--) {
247
- const childIsLast = i === orderedChildren.length - 1;
248
- stack.push([orderedChildren[i], childIndent, multipleChildren, multipleChildren, childIsLast, childGutters, false]);
249
- }
250
- }
251
-
252
- return result;
253
- }
254
-
255
- /**
256
- * Build ASCII prefix string for tree node.
257
- */
258
- function buildTreePrefix(flatNode) {
259
- const { indent, showConnector, isLast, gutters, isVirtualRootChild, multipleRoots } = flatNode;
260
- const displayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
261
- const connector = showConnector && !isVirtualRootChild ? (isLast ? '└─ ' : '├─ ') : '';
262
- const connectorPosition = connector ? displayIndent - 1 : -1;
263
-
264
- const totalChars = displayIndent * 3;
265
- const prefixChars = [];
266
- for (let i = 0; i < totalChars; i++) {
267
- const level = Math.floor(i / 3);
268
- const posInLevel = i % 3;
269
-
270
- const gutter = gutters.find(g => g.position === level);
271
- if (gutter) {
272
- prefixChars.push(posInLevel === 0 ? (gutter.show ? '│' : ' ') : ' ');
273
- } else if (connector && level === connectorPosition) {
274
- if (posInLevel === 0) {
275
- prefixChars.push(isLast ? '└' : '├');
276
- } else if (posInLevel === 1) {
277
- prefixChars.push('─');
278
- } else {
279
- prefixChars.push(' ');
280
- }
281
- } else {
282
- prefixChars.push(' ');
283
- }
284
- }
285
- return prefixChars.join('');
286
- }
287
-
288
- // ============================================================
289
- // FILTERING (pure data)
290
- // ============================================================
291
-
292
- let filterMode = 'default';
293
- let searchQuery = '';
294
-
295
- function hasTextContent(content) {
296
- if (typeof content === 'string') return content.trim().length > 0;
297
- if (Array.isArray(content)) {
298
- for (const c of content) {
299
- if (c.type === 'text' && c.text && c.text.trim().length > 0) return true;
300
- }
301
- }
302
- return false;
303
- }
304
-
305
- function extractContent(content) {
306
- if (typeof content === 'string') return content;
307
- if (Array.isArray(content)) {
308
- return content
309
- .filter(c => c.type === 'text' && c.text)
310
- .map(c => c.text)
311
- .join('');
312
- }
313
- return '';
314
- }
315
-
316
- function getSearchableText(entry, label) {
317
- const parts = [];
318
- if (label) parts.push(label);
319
-
320
- switch (entry.type) {
321
- case 'message': {
322
- const msg = entry.message;
323
- parts.push(msg.role);
324
- if (msg.content) parts.push(extractContent(msg.content));
325
- if (msg.role === 'bashExecution' && msg.command) parts.push(msg.command);
326
- break;
327
- }
328
- case 'custom_message':
329
- parts.push(entry.customType);
330
- parts.push(typeof entry.content === 'string' ? entry.content : extractContent(entry.content));
331
- break;
332
- case 'compaction':
333
- parts.push('compaction');
334
- break;
335
- case 'branch_summary':
336
- parts.push('branch summary', entry.summary);
337
- break;
338
- case 'model_change':
339
- parts.push('model', entry.modelId);
340
- break;
341
- case 'thinking_level_change':
342
- parts.push('thinking', entry.thinkingLevel);
343
- break;
344
- }
345
-
346
- return parts.join(' ').toLowerCase();
347
- }
348
-
349
- /**
350
- * Filter flat nodes based on current filterMode and searchQuery.
351
- */
352
- function filterNodes(flatNodes, currentLeafId) {
353
- const searchTokens = searchQuery.toLowerCase().split(/\s+/).filter(Boolean);
354
-
355
- const filtered = flatNodes.filter(flatNode => {
356
- const entry = flatNode.node.entry;
357
- const label = flatNode.node.label;
358
- const isCurrentLeaf = entry.id === currentLeafId;
359
-
360
- // Always show current leaf
361
- if (isCurrentLeaf) return true;
362
-
363
- // Hide assistant messages with only tool calls (no text) unless error/aborted
364
- if (entry.type === 'message' && entry.message.role === 'assistant') {
365
- const msg = entry.message;
366
- const hasText = hasTextContent(msg.content);
367
- const isErrorOrAborted = msg.stopReason && msg.stopReason !== 'stop' && msg.stopReason !== 'toolUse';
368
- if (!hasText && !isErrorOrAborted) return false;
369
- }
370
-
371
- // Apply filter mode
372
- const isSettingsEntry = ['label', 'custom', 'model_change', 'thinking_level_change'].includes(entry.type);
373
- let passesFilter = true;
374
-
375
- switch (filterMode) {
376
- case 'user-only':
377
- passesFilter = entry.type === 'message' && entry.message.role === 'user';
378
- break;
379
- case 'no-tools':
380
- passesFilter = !isSettingsEntry && !(entry.type === 'message' && entry.message.role === 'toolResult');
381
- break;
382
- case 'labeled-only':
383
- passesFilter = label !== undefined;
384
- break;
385
- case 'all':
386
- passesFilter = true;
387
- break;
388
- default: // 'default'
389
- passesFilter = !isSettingsEntry;
390
- break;
391
- }
392
-
393
- if (!passesFilter) return false;
394
-
395
- // Apply search filter
396
- if (searchTokens.length > 0) {
397
- const nodeText = getSearchableText(entry, label);
398
- if (!searchTokens.every(t => nodeText.includes(t))) return false;
399
- }
400
-
401
- return true;
402
- });
403
-
404
- // Recalculate visual structure based on visible tree
405
- recalculateVisualStructure(filtered, flatNodes);
406
-
407
- return filtered;
408
- }
409
-
410
- /**
411
- * Recompute indentation/connectors for the filtered view
412
- *
413
- * Filtering can hide intermediate entries; descendants attach to the nearest visible ancestor.
414
- * Keep indentation semantics aligned with flattenTree() so single-child chains don't drift right.
415
- */
416
- function recalculateVisualStructure(filteredNodes, allFlatNodes) {
417
- if (filteredNodes.length === 0) return;
418
-
419
- const visibleIds = new Set(filteredNodes.map(n => n.node.entry.id));
420
-
421
- // Build entry map for parent lookup (using full tree)
422
- const entryMap = new Map();
423
- for (const flatNode of allFlatNodes) {
424
- entryMap.set(flatNode.node.entry.id, flatNode);
425
- }
426
-
427
- // Find nearest visible ancestor for a node
428
- function findVisibleAncestor(nodeId) {
429
- let currentId = entryMap.get(nodeId)?.node.entry.parentId;
430
- while (currentId != null) {
431
- if (visibleIds.has(currentId)) {
432
- return currentId;
433
- }
434
- currentId = entryMap.get(currentId)?.node.entry.parentId;
435
- }
436
- return null;
437
- }
438
-
439
- // Build visible tree structure
440
- const visibleParent = new Map();
441
- const visibleChildren = new Map();
442
- visibleChildren.set(null, []); // root-level nodes
443
-
444
- for (const flatNode of filteredNodes) {
445
- const nodeId = flatNode.node.entry.id;
446
- const ancestorId = findVisibleAncestor(nodeId);
447
- visibleParent.set(nodeId, ancestorId);
448
-
449
- if (!visibleChildren.has(ancestorId)) {
450
- visibleChildren.set(ancestorId, []);
451
- }
452
- visibleChildren.get(ancestorId).push(nodeId);
453
- }
454
-
455
- // Update multipleRoots based on visible roots
456
- const visibleRootIds = visibleChildren.get(null);
457
- const multipleRoots = visibleRootIds.length > 1;
458
-
459
- // Build a map for quick lookup: nodeId → FlatNode
460
- const filteredNodeMap = new Map();
461
- for (const flatNode of filteredNodes) {
462
- filteredNodeMap.set(flatNode.node.entry.id, flatNode);
463
- }
464
-
465
- // DFS traversal of visible tree, applying same indentation rules as flattenTree()
466
- // Stack items: [nodeId, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild]
467
- const stack = [];
468
-
469
- // Add visible roots in reverse order (to process in forward order via stack)
470
- for (let i = visibleRootIds.length - 1; i >= 0; i--) {
471
- const isLast = i === visibleRootIds.length - 1;
472
- stack.push([
473
- visibleRootIds[i],
474
- multipleRoots ? 1 : 0,
475
- multipleRoots,
476
- multipleRoots,
477
- isLast,
478
- [],
479
- multipleRoots
480
- ]);
481
- }
482
-
483
- while (stack.length > 0) {
484
- const [nodeId, indent, justBranched, showConnector, isLast, gutters, isVirtualRootChild] = stack.pop();
485
-
486
- const flatNode = filteredNodeMap.get(nodeId);
487
- if (!flatNode) continue;
488
-
489
- // Update this node's visual properties
490
- flatNode.indent = indent;
491
- flatNode.showConnector = showConnector;
492
- flatNode.isLast = isLast;
493
- flatNode.gutters = gutters;
494
- flatNode.isVirtualRootChild = isVirtualRootChild;
495
- flatNode.multipleRoots = multipleRoots;
496
-
497
- // Get visible children of this node
498
- const children = visibleChildren.get(nodeId) || [];
499
- const multipleChildren = children.length > 1;
500
-
501
- // Calculate child indent using same rules as flattenTree():
502
- // - Parent branches (multiple children): children get +1
503
- // - Just branched and indent > 0: children get +1 for visual grouping
504
- // - Single-child chain: stay flat
505
- let childIndent;
506
- if (multipleChildren) {
507
- childIndent = indent + 1;
508
- } else if (justBranched && indent > 0) {
509
- childIndent = indent + 1;
510
- } else {
511
- childIndent = indent;
512
- }
513
-
514
- // Build gutters for children (same logic as flattenTree)
515
- const connectorDisplayed = showConnector && !isVirtualRootChild;
516
- const currentDisplayIndent = multipleRoots ? Math.max(0, indent - 1) : indent;
517
- const connectorPosition = Math.max(0, currentDisplayIndent - 1);
518
- const childGutters = connectorDisplayed
519
- ? [...gutters, { position: connectorPosition, show: !isLast }]
520
- : gutters;
521
-
522
- // Add children in reverse order (to process in forward order via stack)
523
- for (let i = children.length - 1; i >= 0; i--) {
524
- const childIsLast = i === children.length - 1;
525
- stack.push([
526
- children[i],
527
- childIndent,
528
- multipleChildren,
529
- multipleChildren,
530
- childIsLast,
531
- childGutters,
532
- false
533
- ]);
534
- }
535
- }
536
- }
537
-
538
- // ============================================================
539
- // TREE DISPLAY TEXT (pure data -> string)
540
- // ============================================================
541
-
542
- function shortenPath(p) {
543
- if (typeof p !== 'string') return '';
544
- if (p.startsWith('/Users/')) {
545
- const parts = p.split('/');
546
- if (parts.length > 2) return '~' + p.slice(('/Users/' + parts[2]).length);
547
- }
548
- if (p.startsWith('/home/')) {
549
- const parts = p.split('/');
550
- if (parts.length > 2) return '~' + p.slice(('/home/' + parts[2]).length);
551
- }
552
- return p;
553
- }
554
-
555
- function formatToolCall(name, args) {
556
- switch (name) {
557
- case 'read': {
558
- const path = shortenPath(String(args.path || args.file_path || ''));
559
- const offset = args.offset;
560
- const limit = args.limit;
561
- let display = path;
562
- if (offset !== undefined || limit !== undefined) {
563
- const start = offset ?? 1;
564
- const end = limit !== undefined ? start + limit - 1 : '';
565
- display += `:${start}${end ? `-${end}` : ''}`;
566
- }
567
- return `[read: ${display}]`;
568
- }
569
- case 'write':
570
- return `[write: ${shortenPath(String(args.path || args.file_path || ''))}]`;
571
- case 'edit':
572
- return `[edit: ${shortenPath(String(args.path || args.file_path || ''))}]`;
573
- case 'bash': {
574
- const rawCmd = String(args.command || '');
575
- const cmd = rawCmd.replace(/[\n\t]/g, ' ').trim().slice(0, 50);
576
- return `[bash: ${cmd}${rawCmd.length > 50 ? '...' : ''}]`;
577
- }
578
- case 'grep':
579
- return `[grep: /${args.pattern || ''}/ in ${shortenPath(String(args.path || '.'))}]`;
580
- case 'find':
581
- return `[find: ${args.pattern || ''} in ${shortenPath(String(args.path || '.'))}]`;
582
- case 'ls':
583
- return `[ls: ${shortenPath(String(args.path || '.'))}]`;
584
- default: {
585
- const argsStr = JSON.stringify(args).slice(0, 40);
586
- return `[${name}: ${argsStr}${JSON.stringify(args).length > 40 ? '...' : ''}]`;
587
- }
588
- }
589
- }
590
-
591
- function escapeHtml(text) {
592
- const div = document.createElement('div');
593
- div.textContent = text;
594
- return div.innerHTML;
595
- }
596
-
597
- /**
598
- * Truncate string to maxLen chars, append "..." if truncated.
599
- */
600
- function truncate(s, maxLen = 100) {
601
- if (s.length <= maxLen) return s;
602
- return s.slice(0, maxLen) + '...';
603
- }
604
-
605
- /**
606
- * Get display text for tree node (returns HTML string).
607
- */
608
- function getTreeNodeDisplayHtml(entry, label) {
609
- const normalize = s => s.replace(/[\n\t]/g, ' ').trim();
610
- const labelHtml = label ? `<span class="tree-label">[${escapeHtml(label)}]</span> ` : '';
611
-
612
- switch (entry.type) {
613
- case 'message': {
614
- const msg = entry.message;
615
- if (msg.role === 'user') {
616
- const content = truncate(normalize(extractContent(msg.content)));
617
- return labelHtml + `<span class="tree-role-user">user:</span> ${escapeHtml(content)}`;
618
- }
619
- if (msg.role === 'assistant') {
620
- const textContent = truncate(normalize(extractContent(msg.content)));
621
- if (textContent) {
622
- return labelHtml + `<span class="tree-role-assistant">assistant:</span> ${escapeHtml(textContent)}`;
623
- }
624
- if (msg.stopReason === 'aborted') {
625
- return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-muted">(aborted)</span>`;
626
- }
627
- if (msg.errorMessage) {
628
- return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-error">${escapeHtml(truncate(msg.errorMessage))}</span>`;
629
- }
630
- return labelHtml + `<span class="tree-role-assistant">assistant:</span> <span class="tree-muted">(no text)</span>`;
631
- }
632
- if (msg.role === 'toolResult') {
633
- const toolCall = msg.toolCallId ? toolCallMap.get(msg.toolCallId) : null;
634
- if (toolCall) {
635
- return labelHtml + `<span class="tree-role-tool">${escapeHtml(formatToolCall(toolCall.name, toolCall.arguments))}</span>`;
636
- }
637
- return labelHtml + `<span class="tree-role-tool">[${msg.toolName || 'tool'}]</span>`;
638
- }
639
- if (msg.role === 'bashExecution') {
640
- const cmd = truncate(normalize(msg.command || ''));
641
- return labelHtml + `<span class="tree-role-tool">[bash]:</span> ${escapeHtml(cmd)}`;
642
- }
643
- return labelHtml + `<span class="tree-muted">[${msg.role}]</span>`;
644
- }
645
- case 'compaction':
646
- return labelHtml + `<span class="tree-compaction">[compaction: ${Math.round(entry.tokensBefore/1000)}k tokens]</span>`;
647
- case 'branch_summary': {
648
- const summary = truncate(normalize(entry.summary || ''));
649
- return labelHtml + `<span class="tree-branch-summary">[branch summary]:</span> ${escapeHtml(summary)}`;
650
- }
651
- case 'custom_message': {
652
- const content = typeof entry.content === 'string' ? entry.content : extractContent(entry.content);
653
- return labelHtml + `<span class="tree-custom">[${escapeHtml(entry.customType)}]:</span> ${escapeHtml(truncate(normalize(content)))}`;
654
- }
655
- case 'model_change':
656
- return labelHtml + `<span class="tree-muted">[model: ${entry.modelId}]</span>`;
657
- case 'thinking_level_change':
658
- return labelHtml + `<span class="tree-muted">[thinking: ${entry.thinkingLevel}]</span>`;
659
- default:
660
- return labelHtml + `<span class="tree-muted">[${entry.type}]</span>`;
661
- }
662
- }
663
-
664
- // ============================================================
665
- // TREE RENDERING (DOM manipulation)
666
- // ============================================================
667
-
668
- let currentLeafId = leafId;
669
- let currentTargetId = urlTargetId || leafId;
670
- let treeRendered = false;
671
-
672
- function renderTree() {
673
- const tree = buildTree();
674
- const activePathIds = buildActivePathIds(currentLeafId);
675
- const flatNodes = flattenTree(tree, activePathIds);
676
- const filtered = filterNodes(flatNodes, currentLeafId);
677
- const container = document.getElementById('tree-container');
678
-
679
- // Full render only on first call or when filter/search changes
680
- if (!treeRendered) {
681
- container.innerHTML = '';
682
-
683
- for (const flatNode of filtered) {
684
- const entry = flatNode.node.entry;
685
- const isOnPath = activePathIds.has(entry.id);
686
- const isTarget = entry.id === currentTargetId;
687
-
688
- const div = document.createElement('div');
689
- div.className = 'tree-node';
690
- if (isOnPath) div.classList.add('in-path');
691
- if (isTarget) div.classList.add('active');
692
- div.dataset.id = entry.id;
693
-
694
- const prefix = buildTreePrefix(flatNode);
695
- const prefixSpan = document.createElement('span');
696
- prefixSpan.className = 'tree-prefix';
697
- prefixSpan.textContent = prefix;
698
-
699
- const marker = document.createElement('span');
700
- marker.className = 'tree-marker';
701
- marker.textContent = isOnPath ? '•' : ' ';
702
-
703
- const content = document.createElement('span');
704
- content.className = 'tree-content';
705
- content.innerHTML = getTreeNodeDisplayHtml(entry, flatNode.node.label);
706
-
707
- div.appendChild(prefixSpan);
708
- div.appendChild(marker);
709
- div.appendChild(content);
710
- // Navigate to the newest leaf through this node, but scroll to the clicked node
711
- div.addEventListener('click', () => {
712
- if (window.getSelection().toString()) return;
713
- const leafId = findNewestLeaf(entry.id);
714
- navigateTo(leafId, 'target', entry.id);
715
- });
716
-
717
- container.appendChild(div);
718
- }
719
-
720
- treeRendered = true;
721
- } else {
722
- // Just update markers and classes
723
- const nodes = container.querySelectorAll('.tree-node');
724
- for (const node of nodes) {
725
- const id = node.dataset.id;
726
- const isOnPath = activePathIds.has(id);
727
- const isTarget = id === currentTargetId;
728
-
729
- node.classList.toggle('in-path', isOnPath);
730
- node.classList.toggle('active', isTarget);
731
-
732
- const marker = node.querySelector('.tree-marker');
733
- if (marker) {
734
- marker.textContent = isOnPath ? '•' : ' ';
735
- }
736
- }
737
- }
738
-
739
- document.getElementById('tree-status').textContent = `${filtered.length} / ${flatNodes.length} entries`;
740
-
741
- // Scroll active node into view after layout
742
- setTimeout(() => {
743
- const activeNode = container.querySelector('.tree-node.active');
744
- if (activeNode) {
745
- activeNode.scrollIntoView({ block: 'nearest' });
746
- }
747
- }, 0);
748
- }
749
-
750
- function forceTreeRerender() {
751
- treeRendered = false;
752
- renderTree();
753
- }
754
-
755
- // ============================================================
756
- // MESSAGE RENDERING
757
- // ============================================================
758
-
759
- function formatTokens(count) {
760
- if (count < 1000) return count.toString();
761
- if (count < 10000) return (count / 1000).toFixed(1) + 'k';
762
- if (count < 1000000) return Math.round(count / 1000) + 'k';
763
- return (count / 1000000).toFixed(1) + 'M';
764
- }
765
-
766
- function formatTimestamp(ts) {
767
- if (!ts) return '';
768
- const date = new Date(ts);
769
- return date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });
770
- }
771
-
772
- function replaceTabs(text) {
773
- return text.replace(/\t/g, ' ');
774
- }
775
-
776
- /** Safely coerce value to string for display. Returns null if invalid type. */
777
- function str(value) {
778
- if (typeof value === 'string') return value;
779
- if (value == null) return '';
780
- return null;
781
- }
782
-
783
- function getLanguageFromPath(filePath) {
784
- const ext = filePath.split('.').pop()?.toLowerCase();
785
- const extToLang = {
786
- ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',
787
- py: 'python', rb: 'ruby', rs: 'rust', go: 'go', java: 'java',
788
- c: 'c', cpp: 'cpp', h: 'c', hpp: 'cpp', cs: 'csharp',
789
- php: 'php', sh: 'bash', bash: 'bash', zsh: 'bash',
790
- sql: 'sql', html: 'html', css: 'css', scss: 'scss',
791
- json: 'json', yaml: 'yaml', yml: 'yaml', xml: 'xml',
792
- md: 'markdown', dockerfile: 'dockerfile'
793
- };
794
- return extToLang[ext];
795
- }
796
-
797
- function findToolResult(toolCallId) {
798
- for (const entry of entries) {
799
- if (entry.type === 'message' && entry.message.role === 'toolResult') {
800
- if (entry.message.toolCallId === toolCallId) {
801
- return entry.message;
802
- }
803
- }
804
- }
805
- return null;
806
- }
807
-
808
- function formatExpandableOutput(text, maxLines, lang) {
809
- text = replaceTabs(text);
810
- const lines = text.split('\n');
811
- const displayLines = lines.slice(0, maxLines);
812
- const remaining = lines.length - maxLines;
813
-
814
- if (lang) {
815
- let highlighted;
816
- try {
817
- highlighted = hljs.highlight(text, { language: lang }).value;
818
- } catch {
819
- highlighted = escapeHtml(text);
820
- }
821
-
822
- if (remaining > 0) {
823
- const previewCode = displayLines.join('\n');
824
- let previewHighlighted;
825
- try {
826
- previewHighlighted = hljs.highlight(previewCode, { language: lang }).value;
827
- } catch {
828
- previewHighlighted = escapeHtml(previewCode);
829
- }
830
-
831
- return `<div class="tool-output expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
832
- <div class="output-preview"><pre><code class="hljs">${previewHighlighted}</code></pre>
833
- <div class="expand-hint">... (${remaining} more lines)</div></div>
834
- <div class="output-full"><pre><code class="hljs">${highlighted}</code></pre></div></div>`;
835
- }
836
-
837
- return `<div class="tool-output"><pre><code class="hljs">${highlighted}</code></pre></div>`;
838
- }
839
-
840
- // Plain text output
841
- if (remaining > 0) {
842
- let out = '<div class="tool-output expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle(\'expanded\')">';
843
- out += '<div class="output-preview">';
844
- for (const line of displayLines) {
845
- out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
846
- }
847
- out += `<div class="expand-hint">... (${remaining} more lines)</div></div>`;
848
- out += '<div class="output-full">';
849
- for (const line of lines) {
850
- out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
851
- }
852
- out += '</div></div>';
853
- return out;
854
- }
855
-
856
- let out = '<div class="tool-output">';
857
- for (const line of displayLines) {
858
- out += `<div>${escapeHtml(replaceTabs(line))}</div>`;
859
- }
860
- out += '</div>';
861
- return out;
862
- }
863
-
864
- function renderToolCall(call) {
865
- const result = findToolResult(call.id);
866
- const isError = result?.isError || false;
867
- const statusClass = result ? (isError ? 'error' : 'success') : 'pending';
868
-
869
- const getResultText = () => {
870
- if (!result) return '';
871
- const textBlocks = result.content.filter(c => c.type === 'text');
872
- return textBlocks.map(c => c.text).join('\n');
873
- };
874
-
875
- const getResultImages = () => {
876
- if (!result) return [];
877
- return result.content.filter(c => c.type === 'image');
878
- };
879
-
880
- const renderResultImages = () => {
881
- const images = getResultImages();
882
- if (images.length === 0) return '';
883
- return '<div class="tool-images">' +
884
- images.map(img => `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${img.data}" class="tool-image" />`).join('') +
885
- '</div>';
886
- };
887
-
888
- let html = `<div class="tool-execution ${statusClass}">`;
889
- const args = call.arguments || {};
890
- const name = call.name;
891
-
892
- const invalidArg = '<span class="tool-error">[invalid arg]</span>';
893
-
894
- switch (name) {
895
- case 'bash': {
896
- const command = str(args.command);
897
- const cmdDisplay = command === null ? invalidArg : escapeHtml(command || '...');
898
- html += `<div class="tool-command">$ ${cmdDisplay}</div>`;
899
- if (result) {
900
- const output = getResultText().trim();
901
- if (output) html += formatExpandableOutput(output, 5);
902
- }
903
- break;
904
- }
905
- case 'read': {
906
- const filePath = str(args.file_path ?? args.path);
907
- const offset = args.offset;
908
- const limit = args.limit;
909
-
910
- let pathHtml = filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''));
911
- if (filePath !== null && (offset !== undefined || limit !== undefined)) {
912
- const startLine = offset ?? 1;
913
- const endLine = limit !== undefined ? startLine + limit - 1 : '';
914
- pathHtml += `<span class="line-numbers">:${startLine}${endLine ? '-' + endLine : ''}</span>`;
915
- }
916
-
917
- html += `<div class="tool-header"><span class="tool-name">read</span> <span class="tool-path">${pathHtml}</span></div>`;
918
- if (result) {
919
- html += renderResultImages();
920
- const output = getResultText();
921
- const lang = filePath ? getLanguageFromPath(filePath) : null;
922
- if (output) html += formatExpandableOutput(output, 10, lang);
923
- }
924
- break;
925
- }
926
- case 'write': {
927
- const filePath = str(args.file_path ?? args.path);
928
- const content = str(args.content);
929
-
930
- html += `<div class="tool-header"><span class="tool-name">write</span> <span class="tool-path">${filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''))}</span>`;
931
- if (content !== null && content) {
932
- const lines = content.split('\n');
933
- if (lines.length > 10) html += ` <span class="line-count">(${lines.length} lines)</span>`;
934
- }
935
- html += '</div>';
936
-
937
- if (content === null) {
938
- html += `<div class="tool-error">[invalid content arg - expected string]</div>`;
939
- } else if (content) {
940
- const lang = filePath ? getLanguageFromPath(filePath) : null;
941
- html += formatExpandableOutput(content, 10, lang);
942
- }
943
- if (result) {
944
- const output = getResultText().trim();
945
- if (output) html += `<div class="tool-output"><div>${escapeHtml(output)}</div></div>`;
946
- }
947
- break;
948
- }
949
- case 'edit': {
950
- const filePath = str(args.file_path ?? args.path);
951
- html += `<div class="tool-header"><span class="tool-name">edit</span> <span class="tool-path">${filePath === null ? invalidArg : escapeHtml(shortenPath(filePath || ''))}</span></div>`;
952
-
953
- if (result?.details?.diff) {
954
- const diffLines = result.details.diff.split('\n');
955
- html += '<div class="tool-diff">';
956
- for (const line of diffLines) {
957
- const cls = line.match(/^\+/) ? 'diff-added' : line.match(/^-/) ? 'diff-removed' : 'diff-context';
958
- html += `<div class="${cls}">${escapeHtml(replaceTabs(line))}</div>`;
959
- }
960
- html += '</div>';
961
- } else if (result) {
962
- const output = getResultText().trim();
963
- if (output) html += `<div class="tool-output"><pre>${escapeHtml(output)}</pre></div>`;
964
- }
965
- break;
966
- }
967
- case 'ls': {
968
- const dirPath = str(args.path);
969
- const limit = args.limit;
970
-
971
- let pathHtml = dirPath === null ? invalidArg : escapeHtml(shortenPath(dirPath || '.'));
972
- if (limit !== undefined) {
973
- pathHtml += ` <span class="line-count">(limit ${escapeHtml(String(limit))})</span>`;
974
- }
975
-
976
- html += `<div class="tool-header"><span class="tool-name">ls</span> <span class="tool-path">${pathHtml}</span></div>`;
977
- if (result) {
978
- const output = getResultText().trim();
979
- if (output) html += formatExpandableOutput(output, 20);
980
- }
981
- break;
982
- }
983
- default: {
984
- // Check for pre-rendered custom tool HTML
985
- const rendered = renderedTools?.[call.id];
986
- if (rendered?.callHtml || rendered?.resultHtmlCollapsed || rendered?.resultHtmlExpanded) {
987
- // Custom tool with pre-rendered HTML from TUI renderer
988
- if (rendered.callHtml) {
989
- html += `<div class="tool-header ansi-rendered">${rendered.callHtml}</div>`;
990
- } else {
991
- html += `<div class="tool-header"><span class="tool-name">${escapeHtml(name)}</span></div>`;
992
- }
993
-
994
- if (rendered.resultHtmlCollapsed && rendered.resultHtmlExpanded && rendered.resultHtmlCollapsed !== rendered.resultHtmlExpanded) {
995
- // Both collapsed and expanded differ - render expandable section
996
- html += `<div class="tool-output expandable ansi-rendered" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
997
- <div class="output-preview">${rendered.resultHtmlCollapsed}</div>
998
- <div class="output-full">${rendered.resultHtmlExpanded}</div>
999
- </div>`;
1000
- } else if (rendered.resultHtmlExpanded) {
1001
- // Only expanded exists (or collapsed is identical) - show directly
1002
- html += `<div class="tool-output ansi-rendered">${rendered.resultHtmlExpanded}</div>`;
1003
- } else if (result) {
1004
- // No pre-rendered result HTML - fallback to JSON
1005
- const output = getResultText();
1006
- if (output) html += formatExpandableOutput(output, 10);
1007
- }
1008
- } else {
1009
- // Fallback to JSON display (existing behavior)
1010
- html += `<div class="tool-header"><span class="tool-name">${escapeHtml(name)}</span></div>`;
1011
- html += `<div class="tool-output"><pre>${escapeHtml(JSON.stringify(args, null, 2))}</pre></div>`;
1012
- if (result) {
1013
- const output = getResultText();
1014
- if (output) html += formatExpandableOutput(output, 10);
1015
- }
1016
- }
1017
- }
1018
- }
1019
-
1020
- html += '</div>';
1021
- return html;
1022
- }
1023
-
1024
- /**
1025
- * Download the session data as a JSONL file.
1026
- * Reconstructs the original format: header line + entry lines.
1027
- */
1028
- window.downloadSessionJson = function() {
1029
- // Build JSONL content: header first, then all entries
1030
- const lines = [];
1031
- if (header) {
1032
- lines.push(JSON.stringify({ type: 'header', ...header }));
1033
- }
1034
- for (const entry of entries) {
1035
- lines.push(JSON.stringify(entry));
1036
- }
1037
- const jsonlContent = lines.join('\n');
1038
-
1039
- // Create download
1040
- const blob = new Blob([jsonlContent], { type: 'application/x-ndjson' });
1041
- const url = URL.createObjectURL(blob);
1042
- const a = document.createElement('a');
1043
- a.href = url;
1044
- a.download = `${header?.id || 'session'}.jsonl`;
1045
- document.body.appendChild(a);
1046
- a.click();
1047
- document.body.removeChild(a);
1048
- URL.revokeObjectURL(url);
1049
- }
1050
-
1051
- /**
1052
- * Build a shareable URL for a specific message.
1053
- * URL format: base?gistId&leafId=<leafId>&targetId=<entryId>
1054
- */
1055
- function buildShareUrl(entryId) {
1056
- // Check for injected base URL (used when loaded in iframe via srcdoc)
1057
- const baseUrlMeta = document.querySelector('meta[name="pi-share-base-url"]');
1058
- const baseUrl = baseUrlMeta ? baseUrlMeta.content : window.location.href.split('?')[0];
1059
-
1060
- const url = new URL(window.location.href);
1061
- // Find the gist ID (first query param without value, e.g., ?abc123)
1062
- const gistId = Array.from(url.searchParams.keys()).find(k => !url.searchParams.get(k));
1063
-
1064
- // Build the share URL
1065
- const params = new URLSearchParams();
1066
- params.set('leafId', currentLeafId);
1067
- params.set('targetId', entryId);
1068
-
1069
- // If we have an injected base URL (iframe context), use it directly
1070
- if (baseUrlMeta) {
1071
- return `${baseUrl}&${params.toString()}`;
1072
- }
1073
-
1074
- // Otherwise build from current location (direct file access)
1075
- url.search = gistId ? `?${gistId}&${params.toString()}` : `?${params.toString()}`;
1076
- return url.toString();
1077
- }
1078
-
1079
- /**
1080
- * Copy text to clipboard with visual feedback.
1081
- * Uses navigator.clipboard with fallback to execCommand for HTTP contexts.
1082
- */
1083
- async function copyToClipboard(text, button) {
1084
- let success = false;
1085
- try {
1086
- if (navigator.clipboard && navigator.clipboard.writeText) {
1087
- await navigator.clipboard.writeText(text);
1088
- success = true;
1089
- }
1090
- } catch (err) {
1091
- // Clipboard API failed, try fallback
1092
- }
1093
-
1094
- // Fallback for HTTP or when Clipboard API is unavailable
1095
- if (!success) {
1096
- try {
1097
- const textarea = document.createElement('textarea');
1098
- textarea.value = text;
1099
- textarea.style.position = 'fixed';
1100
- textarea.style.opacity = '0';
1101
- document.body.appendChild(textarea);
1102
- textarea.select();
1103
- success = document.execCommand('copy');
1104
- document.body.removeChild(textarea);
1105
- } catch (err) {
1106
- console.error('Failed to copy:', err);
1107
- }
1108
- }
1109
-
1110
- if (success && button) {
1111
- const originalHtml = button.innerHTML;
1112
- button.innerHTML = '✓';
1113
- button.classList.add('copied');
1114
- setTimeout(() => {
1115
- button.innerHTML = originalHtml;
1116
- button.classList.remove('copied');
1117
- }, 1500);
1118
- }
1119
- }
1120
-
1121
- /**
1122
- * Render the copy-link button HTML for a message.
1123
- */
1124
- function renderCopyLinkButton(entryId) {
1125
- return `<button class="copy-link-btn" data-entry-id="${entryId}" title="Copy link to this message">
1126
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1127
- <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/>
1128
- <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>
1129
- </svg>
1130
- </button>`;
1131
- }
1132
-
1133
- function renderEntry(entry) {
1134
- const ts = formatTimestamp(entry.timestamp);
1135
- const tsHtml = ts ? `<div class="message-timestamp">${ts}</div>` : '';
1136
- const entryId = `entry-${entry.id}`;
1137
- const copyBtnHtml = renderCopyLinkButton(entry.id);
1138
-
1139
- if (entry.type === 'message') {
1140
- const msg = entry.message;
1141
-
1142
- if (msg.role === 'user') {
1143
- let html = `<div class="user-message" id="${entryId}">${copyBtnHtml}${tsHtml}`;
1144
- const content = msg.content;
1145
-
1146
- if (Array.isArray(content)) {
1147
- const images = content.filter(c => c.type === 'image');
1148
- if (images.length > 0) {
1149
- html += '<div class="message-images">';
1150
- for (const img of images) {
1151
- html += `<img src="data:${escapeHtml(img.mimeType || 'image/png')};base64,${img.data}" class="message-image" />`;
1152
- }
1153
- html += '</div>';
1154
- }
1155
- }
1156
-
1157
- const text = typeof content === 'string' ? content :
1158
- content.filter(c => c.type === 'text').map(c => c.text).join('\n');
1159
- if (text.trim()) {
1160
- html += `<div class="markdown-content">${safeMarkedParse(text)}</div>`;
1161
- }
1162
- html += '</div>';
1163
- return html;
1164
- }
1165
-
1166
- if (msg.role === 'assistant') {
1167
- let html = `<div class="assistant-message" id="${entryId}">${copyBtnHtml}${tsHtml}`;
1168
-
1169
- for (const block of msg.content) {
1170
- if (block.type === 'text' && block.text.trim()) {
1171
- html += `<div class="assistant-text markdown-content">${safeMarkedParse(block.text)}</div>`;
1172
- } else if (block.type === 'thinking' && block.thinking.trim()) {
1173
- html += `<div class="thinking-block">
1174
- <div class="thinking-text">${escapeHtml(block.thinking)}</div>
1175
- <div class="thinking-collapsed">Thinking ...</div>
1176
- </div>`;
1177
- }
1178
- }
1179
-
1180
- for (const block of msg.content) {
1181
- if (block.type === 'toolCall') {
1182
- html += renderToolCall(block);
1183
- }
1184
- }
1185
-
1186
- if (msg.stopReason === 'aborted') {
1187
- html += '<div class="error-text">Aborted</div>';
1188
- } else if (msg.stopReason === 'error') {
1189
- html += `<div class="error-text">Error: ${escapeHtml(msg.errorMessage || 'Unknown error')}</div>`;
1190
- }
1191
-
1192
- html += '</div>';
1193
- return html;
1194
- }
1195
-
1196
- if (msg.role === 'bashExecution') {
1197
- const isError = msg.cancelled || (msg.exitCode !== 0 && msg.exitCode !== null);
1198
- let html = `<div class="tool-execution ${isError ? 'error' : 'success'}" id="${entryId}">${tsHtml}`;
1199
- html += `<div class="tool-command">$ ${escapeHtml(msg.command)}</div>`;
1200
- if (msg.output) html += formatExpandableOutput(msg.output, 10);
1201
- if (msg.cancelled) {
1202
- html += '<div style="color: var(--warning)">(cancelled)</div>';
1203
- } else if (msg.exitCode !== 0 && msg.exitCode !== null) {
1204
- html += `<div style="color: var(--error)">(exit ${msg.exitCode})</div>`;
1205
- }
1206
- html += '</div>';
1207
- return html;
1208
- }
1209
-
1210
- if (msg.role === 'toolResult') return '';
1211
- }
1212
-
1213
- if (entry.type === 'model_change') {
1214
- return `<div class="model-change" id="${entryId}">${tsHtml}Switched to model: <span class="model-name">${escapeHtml(entry.provider)}/${escapeHtml(entry.modelId)}</span></div>`;
1215
- }
1216
-
1217
- if (entry.type === 'compaction') {
1218
- return `<div class="compaction" id="${entryId}" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
1219
- <div class="compaction-label">[compaction]</div>
1220
- <div class="compaction-collapsed">Compacted from ${entry.tokensBefore.toLocaleString()} tokens</div>
1221
- <div class="compaction-content"><strong>Compacted from ${entry.tokensBefore.toLocaleString()} tokens</strong>\n\n${escapeHtml(entry.summary)}</div>
1222
- </div>`;
1223
- }
1224
-
1225
- if (entry.type === 'branch_summary') {
1226
- return `<div class="branch-summary" id="${entryId}">${tsHtml}
1227
- <div class="branch-summary-header">Branch Summary</div>
1228
- <div class="markdown-content">${safeMarkedParse(entry.summary)}</div>
1229
- </div>`;
1230
- }
1231
-
1232
- if (entry.type === 'custom_message' && entry.display) {
1233
- return `<div class="hook-message" id="${entryId}">${tsHtml}
1234
- <div class="hook-type">[${escapeHtml(entry.customType)}]</div>
1235
- <div class="markdown-content">${safeMarkedParse(typeof entry.content === 'string' ? entry.content : JSON.stringify(entry.content))}</div>
1236
- </div>`;
1237
- }
1238
-
1239
- return '';
1240
- }
1241
-
1242
- // ============================================================
1243
- // HEADER / STATS
1244
- // ============================================================
1245
-
1246
- function computeStats(entryList) {
1247
- let userMessages = 0, assistantMessages = 0, toolResults = 0;
1248
- let customMessages = 0, compactions = 0, branchSummaries = 0, toolCalls = 0;
1249
- const tokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
1250
- const cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
1251
- const models = new Set();
1252
-
1253
- for (const entry of entryList) {
1254
- if (entry.type === 'message') {
1255
- const msg = entry.message;
1256
- if (msg.role === 'user') userMessages++;
1257
- if (msg.role === 'assistant') {
1258
- assistantMessages++;
1259
- if (msg.model) models.add(msg.provider ? `${msg.provider}/${msg.model}` : msg.model);
1260
- if (msg.usage) {
1261
- tokens.input += msg.usage.input || 0;
1262
- tokens.output += msg.usage.output || 0;
1263
- tokens.cacheRead += msg.usage.cacheRead || 0;
1264
- tokens.cacheWrite += msg.usage.cacheWrite || 0;
1265
- if (msg.usage.cost) {
1266
- cost.input += msg.usage.cost.input || 0;
1267
- cost.output += msg.usage.cost.output || 0;
1268
- cost.cacheRead += msg.usage.cost.cacheRead || 0;
1269
- cost.cacheWrite += msg.usage.cost.cacheWrite || 0;
1270
- }
1271
- }
1272
- toolCalls += msg.content.filter(c => c.type === 'toolCall').length;
1273
- }
1274
- if (msg.role === 'toolResult') toolResults++;
1275
- } else if (entry.type === 'compaction') {
1276
- compactions++;
1277
- } else if (entry.type === 'branch_summary') {
1278
- branchSummaries++;
1279
- } else if (entry.type === 'custom_message') {
1280
- customMessages++;
1281
- }
1282
- }
1283
-
1284
- return { userMessages, assistantMessages, toolResults, customMessages, compactions, branchSummaries, toolCalls, tokens, cost, models: Array.from(models) };
1285
- }
1286
-
1287
- const globalStats = computeStats(entries);
1288
-
1289
- function renderHeader() {
1290
- const totalCost = globalStats.cost.input + globalStats.cost.output + globalStats.cost.cacheRead + globalStats.cost.cacheWrite;
1291
-
1292
- const tokenParts = [];
1293
- if (globalStats.tokens.input) tokenParts.push(`↑${formatTokens(globalStats.tokens.input)}`);
1294
- if (globalStats.tokens.output) tokenParts.push(`↓${formatTokens(globalStats.tokens.output)}`);
1295
- if (globalStats.tokens.cacheRead) tokenParts.push(`R${formatTokens(globalStats.tokens.cacheRead)}`);
1296
- if (globalStats.tokens.cacheWrite) tokenParts.push(`W${formatTokens(globalStats.tokens.cacheWrite)}`);
1297
-
1298
- const msgParts = [];
1299
- if (globalStats.userMessages) msgParts.push(`${globalStats.userMessages} user`);
1300
- if (globalStats.assistantMessages) msgParts.push(`${globalStats.assistantMessages} assistant`);
1301
- if (globalStats.toolResults) msgParts.push(`${globalStats.toolResults} tool results`);
1302
- if (globalStats.customMessages) msgParts.push(`${globalStats.customMessages} custom`);
1303
- if (globalStats.compactions) msgParts.push(`${globalStats.compactions} compactions`);
1304
- if (globalStats.branchSummaries) msgParts.push(`${globalStats.branchSummaries} branch summaries`);
1305
-
1306
- let html = `
1307
- <div class="header">
1308
- <h1>Session: ${escapeHtml(header?.id || 'unknown')}</h1>
1309
- <div class="help-bar">
1310
- <span class="help-hint">T toggle thinking · O toggle tools</span>
1311
- <div class="help-actions">
1312
- <button type="button" class="header-toggle-btn" data-action="toggle-thinking" title="Toggle thinking (T)">Toggle thinking</button>
1313
- <button type="button" class="header-toggle-btn" data-action="toggle-tools" title="Toggle tools (O)">Toggle tools</button>
1314
- <button type="button" class="download-json-btn" onclick="downloadSessionJson()" title="Download session as JSONL">↓ JSONL</button>
1315
- </div>
1316
- </div>
1317
- <div class="header-info">
1318
- <div class="info-item"><span class="info-label">Date:</span><span class="info-value">${header?.timestamp ? new Date(header.timestamp).toLocaleString() : 'unknown'}</span></div>
1319
- <div class="info-item"><span class="info-label">Models:</span><span class="info-value">${globalStats.models.join(', ') || 'unknown'}</span></div>
1320
- <div class="info-item"><span class="info-label">Messages:</span><span class="info-value">${msgParts.join(', ') || '0'}</span></div>
1321
- <div class="info-item"><span class="info-label">Tool Calls:</span><span class="info-value">${globalStats.toolCalls}</span></div>
1322
- <div class="info-item"><span class="info-label">Tokens:</span><span class="info-value">${tokenParts.join(' ') || '0'}</span></div>
1323
- <div class="info-item"><span class="info-label">Cost:</span><span class="info-value">$${totalCost.toFixed(3)}</span></div>
1324
- </div>
1325
- </div>`;
1326
-
1327
- // Render system prompt (user's base prompt, applies to all providers)
1328
- if (systemPrompt) {
1329
- const lines = systemPrompt.split('\n');
1330
- const previewLines = 10;
1331
- if (lines.length > previewLines) {
1332
- const preview = lines.slice(0, previewLines).join('\n');
1333
- const remaining = lines.length - previewLines;
1334
- html += `<div class="system-prompt expandable" onclick="if(window.getSelection().toString())return;this.classList.toggle('expanded')">
1335
- <div class="system-prompt-header">System Prompt</div>
1336
- <div class="system-prompt-preview">${escapeHtml(preview)}</div>
1337
- <div class="system-prompt-expand-hint">... (${remaining} more lines, click to expand)</div>
1338
- <div class="system-prompt-full">${escapeHtml(systemPrompt)}</div>
1339
- </div>`;
1340
- } else {
1341
- html += `<div class="system-prompt">
1342
- <div class="system-prompt-header">System Prompt</div>
1343
- <div class="system-prompt-full" style="display: block">${escapeHtml(systemPrompt)}</div>
1344
- </div>`;
1345
- }
1346
- }
1347
-
1348
- if (tools && tools.length > 0) {
1349
- html += `<div class="tools-list">
1350
- <div class="tools-header">Available Tools</div>
1351
- <div class="tools-content">
1352
- ${tools.map(t => {
1353
- const hasParams = t.parameters && typeof t.parameters === 'object' && t.parameters.properties && Object.keys(t.parameters.properties).length > 0;
1354
- if (!hasParams) {
1355
- return `<div class="tool-item"><span class="tool-item-name">${escapeHtml(t.name)}</span> - <span class="tool-item-desc">${escapeHtml(t.description)}</span></div>`;
1356
- }
1357
- const params = t.parameters;
1358
- const properties = params.properties;
1359
- const required = params.required || [];
1360
- let paramsHtml = '';
1361
- for (const [name, prop] of Object.entries(properties)) {
1362
- const isRequired = required.includes(name);
1363
- const typeStr = prop.type || 'any';
1364
- const reqLabel = isRequired ? '<span class="tool-param-required">required</span>' : '<span class="tool-param-optional">optional</span>';
1365
- paramsHtml += `<div class="tool-param"><span class="tool-param-name">${escapeHtml(name)}</span> <span class="tool-param-type">${escapeHtml(typeStr)}</span> ${reqLabel}`;
1366
- if (prop.description) {
1367
- paramsHtml += `<div class="tool-param-desc">${escapeHtml(prop.description)}</div>`;
1368
- }
1369
- paramsHtml += `</div>`;
1370
- }
1371
- return `<div class="tool-item" onclick="if(window.getSelection().toString())return;this.classList.toggle('params-expanded')"><span class="tool-item-name">${escapeHtml(t.name)}</span> - <span class="tool-item-desc">${escapeHtml(t.description)}</span> <span class="tool-params-hint"></span><div class="tool-params-content">${paramsHtml}</div></div>`;
1372
- }).join('')}
1373
- </div>
1374
- </div>`;
1375
- }
1376
-
1377
- return html;
1378
- }
1379
-
1380
- // ============================================================
1381
- // NAVIGATION
1382
- // ============================================================
1383
-
1384
- // Cache for rendered entry DOM nodes
1385
- const entryCache = new Map();
1386
-
1387
- function renderEntryToNode(entry) {
1388
- // Check cache first
1389
- if (entryCache.has(entry.id)) {
1390
- return entryCache.get(entry.id).cloneNode(true);
1391
- }
1392
-
1393
- // Render to HTML string, then parse to node
1394
- const html = renderEntry(entry);
1395
- if (!html) return null;
1396
-
1397
- const template = document.createElement('template');
1398
- template.innerHTML = html;
1399
- const node = template.content.firstElementChild;
1400
-
1401
- // Cache the node
1402
- if (node) {
1403
- entryCache.set(entry.id, node.cloneNode(true));
1404
- }
1405
- return node;
1406
- }
1407
-
1408
- function navigateTo(targetId, scrollMode = 'target', scrollToEntryId = null) {
1409
- currentLeafId = targetId;
1410
- currentTargetId = scrollToEntryId || targetId;
1411
- const path = getPath(targetId);
1412
-
1413
- renderTree();
1414
-
1415
- document.getElementById('header-container').innerHTML = renderHeader();
1416
- attachHeaderHandlers();
1417
-
1418
- // Build messages using cached DOM nodes
1419
- const messagesEl = document.getElementById('messages');
1420
- const fragment = document.createDocumentFragment();
1421
-
1422
- for (const entry of path) {
1423
- const node = renderEntryToNode(entry);
1424
- if (node) {
1425
- fragment.appendChild(node);
1426
- }
1427
- }
1428
-
1429
- messagesEl.innerHTML = '';
1430
- messagesEl.appendChild(fragment);
1431
-
1432
- // Attach click handlers for copy-link buttons
1433
- messagesEl.querySelectorAll('.copy-link-btn').forEach(btn => {
1434
- btn.addEventListener('click', (e) => {
1435
- e.stopPropagation();
1436
- const entryId = btn.dataset.entryId;
1437
- const shareUrl = buildShareUrl(entryId);
1438
- copyToClipboard(shareUrl, btn);
1439
- });
1440
- });
1441
-
1442
- // Use setTimeout(0) to ensure DOM is fully laid out before scrolling
1443
- setTimeout(() => {
1444
- const content = document.getElementById('content');
1445
- if (scrollMode === 'bottom') {
1446
- content.scrollTop = content.scrollHeight;
1447
- } else if (scrollMode === 'target') {
1448
- // If scrollToEntryId is provided, scroll to that specific entry
1449
- const scrollTargetId = scrollToEntryId || targetId;
1450
- const targetEl = document.getElementById(`entry-${scrollTargetId}`);
1451
- if (targetEl) {
1452
- targetEl.scrollIntoView({ block: 'center' });
1453
- // Briefly highlight the target message
1454
- if (scrollToEntryId) {
1455
- targetEl.classList.add('highlight');
1456
- setTimeout(() => targetEl.classList.remove('highlight'), 2000);
1457
- }
1458
- }
1459
- }
1460
- }, 0);
1461
- }
1462
-
1463
- // ============================================================
1464
- // INITIALIZATION
1465
- // ============================================================
1466
-
1467
- // Configure marked with syntax highlighting and TUI-compatible HTML handling
1468
- const strictStrikethroughRegex = /^(~~)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/;
1469
-
1470
- marked.use({
1471
- breaks: true,
1472
- gfm: true,
1473
- tokenizer: {
1474
- // Treat HTML-like input as plain text so tags are shown verbatim,
1475
- // matching the TUI markdown renderer.
1476
- html() {
1477
- return undefined;
1478
- },
1479
- tag() {
1480
- return undefined;
1481
- },
1482
- del(src) {
1483
- const match = strictStrikethroughRegex.exec(src);
1484
- if (!match) return undefined;
1485
- return {
1486
- type: 'del',
1487
- raw: match[0],
1488
- text: match[2],
1489
- tokens: this.lexer.inlineTokens(match[2])
1490
- };
1491
- }
1492
- },
1493
- renderer: {
1494
- // Sanitize link URLs to prevent javascript:/vbscript:/data: XSS
1495
- link(token) {
1496
- const href = (token.href || '').trim();
1497
- if (/^\s*(javascript|vbscript|data):/i.test(href)) {
1498
- return this.parser.parseInline(token.tokens);
1499
- }
1500
- let out = '<a href="' + escapeHtml(href) + '"';
1501
- if (token.title) {
1502
- out += ' title="' + escapeHtml(token.title) + '"';
1503
- }
1504
- out += '>' + this.parser.parseInline(token.tokens) + '</a>';
1505
- return out;
1506
- },
1507
- // Sanitize image src URLs
1508
- image(token) {
1509
- const href = (token.href || '').trim();
1510
- if (/^\s*(javascript|vbscript|data):/i.test(href)) {
1511
- return escapeHtml(token.text || '');
1512
- }
1513
- let out = '<img src="' + escapeHtml(href) + '" alt="' + escapeHtml(token.text || '') + '"';
1514
- if (token.title) {
1515
- out += ' title="' + escapeHtml(token.title) + '"';
1516
- }
1517
- out += '>';
1518
- return out;
1519
- },
1520
- // Code blocks: syntax highlight, no HTML escaping
1521
- code(token) {
1522
- const code = token.text;
1523
- const lang = token.lang;
1524
- let highlighted;
1525
- if (lang && hljs.getLanguage(lang)) {
1526
- try {
1527
- highlighted = hljs.highlight(code, { language: lang }).value;
1528
- } catch {
1529
- highlighted = escapeHtml(code);
1530
- }
1531
- } else {
1532
- // Auto-detect language if not specified
1533
- try {
1534
- highlighted = hljs.highlightAuto(code).value;
1535
- } catch {
1536
- highlighted = escapeHtml(code);
1537
- }
1538
- }
1539
- return `<pre><code class="hljs">${highlighted}</code></pre>`;
1540
- },
1541
- // Inline code: escape HTML
1542
- codespan(token) {
1543
- return `<code>${escapeHtml(token.text)}</code>`;
1544
- }
1545
- }
1546
- });
1547
-
1548
- // Simple marked parse (escaping handled in renderers)
1549
- function safeMarkedParse(text) {
1550
- return marked.parse(text);
1551
- }
1552
-
1553
- // Search input
1554
- const searchInput = document.getElementById('tree-search');
1555
- searchInput.addEventListener('input', (e) => {
1556
- searchQuery = e.target.value;
1557
- forceTreeRerender();
1558
- });
1559
-
1560
- // Filter buttons
1561
- document.querySelectorAll('.filter-btn').forEach(btn => {
1562
- btn.addEventListener('click', () => {
1563
- document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
1564
- btn.classList.add('active');
1565
- filterMode = btn.dataset.filter;
1566
- forceTreeRerender();
1567
- });
1568
- });
1569
-
1570
- // Sidebar toggle
1571
- const sidebar = document.getElementById('sidebar');
1572
- const overlay = document.getElementById('sidebar-overlay');
1573
- const hamburger = document.getElementById('hamburger');
1574
- const sidebarResizer = document.getElementById('sidebar-resizer');
1575
- const SIDEBAR_WIDTH_STORAGE_KEY = 'pi-share:v1:sidebar-width';
1576
- const MIN_CONTENT_WIDTH = 320;
1577
-
1578
- function isMobileLayout() {
1579
- return window.matchMedia('(max-width: 900px)').matches;
1580
- }
1581
-
1582
- function getSidebarBounds() {
1583
- const rootStyles = getComputedStyle(document.documentElement);
1584
- const minWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-min-width')) || 240;
1585
- const maxWidth = parseFloat(rootStyles.getPropertyValue('--sidebar-max-width')) || 720;
1586
- const viewportMaxWidth = window.innerWidth - MIN_CONTENT_WIDTH;
1587
- return {
1588
- minWidth,
1589
- maxWidth: Math.max(minWidth, Math.min(maxWidth, viewportMaxWidth))
1590
- };
1591
- }
1592
-
1593
- function clampSidebarWidth(width) {
1594
- const { minWidth, maxWidth } = getSidebarBounds();
1595
- return Math.max(minWidth, Math.min(maxWidth, width));
1596
- }
1597
-
1598
- function applySidebarWidth(width) {
1599
- document.documentElement.style.setProperty('--sidebar-width', `${Math.round(clampSidebarWidth(width))}px`);
1600
- }
1601
-
1602
- function loadSidebarWidth() {
1603
- try {
1604
- const raw = localStorage.getItem(SIDEBAR_WIDTH_STORAGE_KEY);
1605
- if (raw === null) return null;
1606
- const width = Number(raw);
1607
- return Number.isFinite(width) ? width : null;
1608
- } catch {
1609
- return null;
1610
- }
1611
- }
1612
-
1613
- function saveSidebarWidth(width) {
1614
- try {
1615
- localStorage.setItem(SIDEBAR_WIDTH_STORAGE_KEY, String(Math.round(clampSidebarWidth(width))));
1616
- } catch {
1617
- // Ignore storage failures (e.g. private browsing restrictions)
1618
- }
1619
- }
1620
-
1621
- function setupSidebarResize() {
1622
- const savedWidth = loadSidebarWidth();
1623
- if (savedWidth !== null) {
1624
- applySidebarWidth(savedWidth);
1625
- }
1626
-
1627
- if (!sidebarResizer) return;
1628
-
1629
- let cleanupDrag = null;
1630
-
1631
- const stopDrag = (pointerId) => {
1632
- if (cleanupDrag) {
1633
- cleanupDrag(pointerId);
1634
- cleanupDrag = null;
1635
- }
1636
- };
1637
-
1638
- sidebarResizer.addEventListener('pointerdown', (e) => {
1639
- if (isMobileLayout()) return;
1640
-
1641
- e.preventDefault();
1642
- const startX = e.clientX;
1643
- const startWidth = sidebar.getBoundingClientRect().width;
1644
- document.body.classList.add('sidebar-resizing');
1645
- sidebarResizer.setPointerCapture?.(e.pointerId);
1646
-
1647
- const onPointerMove = (event) => {
1648
- applySidebarWidth(startWidth + (event.clientX - startX));
1649
- };
1650
-
1651
- cleanupDrag = (pointerIdToRelease) => {
1652
- document.body.classList.remove('sidebar-resizing');
1653
- sidebarResizer.releasePointerCapture?.(pointerIdToRelease);
1654
- window.removeEventListener('pointermove', onPointerMove);
1655
- window.removeEventListener('pointerup', onPointerUp);
1656
- window.removeEventListener('pointercancel', onPointerCancel);
1657
- saveSidebarWidth(sidebar.getBoundingClientRect().width);
1658
- };
1659
-
1660
- const onPointerUp = (event) => stopDrag(event.pointerId);
1661
- const onPointerCancel = (event) => stopDrag(event.pointerId);
1662
-
1663
- window.addEventListener('pointermove', onPointerMove);
1664
- window.addEventListener('pointerup', onPointerUp);
1665
- window.addEventListener('pointercancel', onPointerCancel);
1666
- });
1667
-
1668
- sidebarResizer.addEventListener('dblclick', () => {
1669
- if (isMobileLayout()) return;
1670
- applySidebarWidth(400);
1671
- saveSidebarWidth(400);
1672
- });
1673
-
1674
- window.addEventListener('resize', () => {
1675
- if (isMobileLayout()) return;
1676
- applySidebarWidth(sidebar.getBoundingClientRect().width);
1677
- });
1678
- }
1679
-
1680
- setupSidebarResize();
1681
-
1682
- hamburger.addEventListener('click', () => {
1683
- sidebar.classList.add('open');
1684
- overlay.classList.add('open');
1685
- hamburger.style.display = 'none';
1686
- });
1687
-
1688
- const closeSidebar = () => {
1689
- sidebar.classList.remove('open');
1690
- overlay.classList.remove('open');
1691
- hamburger.style.display = '';
1692
- };
1693
-
1694
- overlay.addEventListener('click', closeSidebar);
1695
- document.getElementById('sidebar-close').addEventListener('click', closeSidebar);
1696
-
1697
- // Toggle states
1698
- let thinkingExpanded = true;
1699
- let toolOutputsExpanded = false;
1700
-
1701
- const toggleThinking = () => {
1702
- thinkingExpanded = !thinkingExpanded;
1703
- document.querySelectorAll('.thinking-text').forEach(el => {
1704
- el.style.display = thinkingExpanded ? '' : 'none';
1705
- });
1706
- document.querySelectorAll('.thinking-collapsed').forEach(el => {
1707
- el.style.display = thinkingExpanded ? 'none' : 'block';
1708
- });
1709
- };
1710
-
1711
- const toggleToolOutputs = () => {
1712
- toolOutputsExpanded = !toolOutputsExpanded;
1713
- document.querySelectorAll('.tool-output.expandable').forEach(el => {
1714
- el.classList.toggle('expanded', toolOutputsExpanded);
1715
- });
1716
- document.querySelectorAll('.compaction').forEach(el => {
1717
- el.classList.toggle('expanded', toolOutputsExpanded);
1718
- });
1719
- };
1720
-
1721
- const attachHeaderHandlers = () => {
1722
- document.querySelector('[data-action="toggle-thinking"]')?.addEventListener('click', toggleThinking);
1723
- document.querySelector('[data-action="toggle-tools"]')?.addEventListener('click', toggleToolOutputs);
1724
- };
1725
-
1726
- const isEditableTarget = (element) => {
1727
- if (!element) return false;
1728
- const tagName = element.tagName;
1729
- if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT' || tagName === 'BUTTON') {
1730
- return true;
1731
- }
1732
- return element.isContentEditable || Boolean(element.closest?.('[contenteditable="true"]'));
1733
- };
1734
-
1735
- // Keyboard shortcuts
1736
- document.addEventListener('keydown', (e) => {
1737
- if (e.key === 'Escape') {
1738
- searchInput.value = '';
1739
- searchQuery = '';
1740
- navigateTo(leafId, 'bottom');
1741
- }
1742
-
1743
- if (isEditableTarget(document.activeElement)) {
1744
- return;
1745
- }
1746
-
1747
- const key = e.key.toLowerCase();
1748
- if (key === 't') {
1749
- e.preventDefault();
1750
- toggleThinking();
1751
- } else if (key === 'o') {
1752
- e.preventDefault();
1753
- toggleToolOutputs();
1754
- }
1755
- });
1756
-
1757
- // Initial render
1758
- // If URL has targetId, scroll to that specific message; otherwise stay at top
1759
- if (leafId) {
1760
- if (urlTargetId && byId.has(urlTargetId)) {
1761
- // Deep link: navigate to leaf and scroll to target message
1762
- navigateTo(leafId, 'target', urlTargetId);
1763
- } else {
1764
- navigateTo(leafId, 'none');
1765
- }
1766
- } else if (entries.length > 0) {
1767
- // Fallback: use last entry if no leafId
1768
- navigateTo(entries[entries.length - 1].id, 'none');
1769
- }
1770
- })();