pi-usereq 0.7.0 → 0.11.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 (773) hide show
  1. package/.gitignore +2 -0
  2. package/CHANGELOG.md +24 -0
  3. package/README.md +1 -1
  4. package/docs/pi.dev/coding-agent-docs/custom-provider.md +42 -1
  5. package/docs/pi.dev/coding-agent-docs/extensions.md +302 -28
  6. package/docs/pi.dev/coding-agent-docs/keybindings.md +23 -1
  7. package/docs/pi.dev/coding-agent-docs/models.md +3 -0
  8. package/docs/pi.dev/coding-agent-docs/packages.md +2 -2
  9. package/docs/pi.dev/coding-agent-docs/prompt-templates.md +21 -0
  10. package/docs/pi.dev/coding-agent-docs/providers.md +1 -0
  11. package/docs/pi.dev/coding-agent-docs/rpc.md +36 -6
  12. package/docs/pi.dev/coding-agent-docs/sdk.md +30 -5
  13. package/docs/pi.dev/coding-agent-docs/session.md +1 -1
  14. package/docs/pi.dev/coding-agent-docs/settings.md +2 -1
  15. package/docs/pi.dev/coding-agent-docs/skills.md +12 -12
  16. package/docs/pi.dev/coding-agent-docs/tree.md +2 -0
  17. package/docs/pi.dev/coding-agent-docs/tui.md +31 -0
  18. package/docs/pi.dev/mom-docs/new.md +4 -4
  19. package/package.json +1 -1
  20. package/pi-usereq/docs/REFERENCES.md +5214 -24470
  21. package/pi-usereq/docs/REQUIREMENTS.md +307 -170
  22. package/pi-usereq/docs/WORKFLOW.md +334 -316
  23. package/pi.dev-src/pi-mono/agent/src/agent-loop.ts +683 -0
  24. package/pi.dev-src/pi-mono/agent/src/agent.ts +543 -0
  25. package/pi.dev-src/pi-mono/agent/src/index.ts +8 -0
  26. package/pi.dev-src/pi-mono/agent/src/proxy.ts +367 -0
  27. package/pi.dev-src/pi-mono/agent/src/types.ts +364 -0
  28. package/pi.dev-src/pi-mono/agent/test/agent-loop.test.ts +1181 -0
  29. package/pi.dev-src/pi-mono/agent/test/agent.test.ts +463 -0
  30. package/pi.dev-src/pi-mono/agent/test/e2e.test.ts +404 -0
  31. package/pi.dev-src/pi-mono/agent/test/utils/calculate.ts +32 -0
  32. package/pi.dev-src/pi-mono/agent/test/utils/get-current-time.ts +46 -0
  33. package/pi.dev-src/pi-mono/agent/vitest.config.ts +9 -0
  34. package/pi.dev-src/pi-mono/ai/bedrock-provider.d.ts +1 -0
  35. package/pi.dev-src/pi-mono/ai/bedrock-provider.js +1 -0
  36. package/pi.dev-src/pi-mono/ai/scripts/generate-models.ts +1635 -0
  37. package/pi.dev-src/pi-mono/ai/scripts/generate-test-image.ts +34 -0
  38. package/pi.dev-src/pi-mono/ai/src/api-registry.ts +98 -0
  39. package/pi.dev-src/pi-mono/ai/src/bedrock-provider.ts +6 -0
  40. package/pi.dev-src/pi-mono/ai/src/cli.ts +133 -0
  41. package/pi.dev-src/pi-mono/ai/src/env-api-keys.ts +134 -0
  42. package/pi.dev-src/pi-mono/ai/src/index.ts +35 -0
  43. package/pi.dev-src/pi-mono/ai/src/models.generated.ts +14928 -0
  44. package/pi.dev-src/pi-mono/ai/src/models.ts +82 -0
  45. package/pi.dev-src/pi-mono/ai/src/oauth.ts +1 -0
  46. package/pi.dev-src/pi-mono/ai/src/providers/amazon-bedrock.ts +929 -0
  47. package/pi.dev-src/pi-mono/ai/src/providers/anthropic.ts +1125 -0
  48. package/pi.dev-src/pi-mono/ai/src/providers/azure-openai-responses.ts +253 -0
  49. package/pi.dev-src/pi-mono/ai/src/providers/faux.ts +499 -0
  50. package/pi.dev-src/pi-mono/ai/src/providers/github-copilot-headers.ts +37 -0
  51. package/pi.dev-src/pi-mono/ai/src/providers/google-gemini-cli.ts +996 -0
  52. package/pi.dev-src/pi-mono/ai/src/providers/google-shared.ts +354 -0
  53. package/pi.dev-src/pi-mono/ai/src/providers/google-vertex.ts +543 -0
  54. package/pi.dev-src/pi-mono/ai/src/providers/google.ts +500 -0
  55. package/pi.dev-src/pi-mono/ai/src/providers/mistral.ts +629 -0
  56. package/pi.dev-src/pi-mono/ai/src/providers/openai-codex-responses.ts +984 -0
  57. package/pi.dev-src/pi-mono/ai/src/providers/openai-completions.ts +1063 -0
  58. package/pi.dev-src/pi-mono/ai/src/providers/openai-responses-shared.ts +539 -0
  59. package/pi.dev-src/pi-mono/ai/src/providers/openai-responses.ts +264 -0
  60. package/pi.dev-src/pi-mono/ai/src/providers/register-builtins.ts +433 -0
  61. package/pi.dev-src/pi-mono/ai/src/providers/simple-options.ts +47 -0
  62. package/pi.dev-src/pi-mono/ai/src/providers/transform-messages.ts +220 -0
  63. package/pi.dev-src/pi-mono/ai/src/stream.ts +59 -0
  64. package/pi.dev-src/pi-mono/ai/src/types.ts +417 -0
  65. package/pi.dev-src/pi-mono/ai/src/utils/event-stream.ts +87 -0
  66. package/pi.dev-src/pi-mono/ai/src/utils/hash.ts +13 -0
  67. package/pi.dev-src/pi-mono/ai/src/utils/headers.ts +7 -0
  68. package/pi.dev-src/pi-mono/ai/src/utils/json-parse.ts +124 -0
  69. package/pi.dev-src/pi-mono/ai/src/utils/overflow.ts +138 -0
  70. package/pi.dev-src/pi-mono/ai/src/utils/sanitize-unicode.ts +25 -0
  71. package/pi.dev-src/pi-mono/ai/src/utils/typebox-helpers.ts +24 -0
  72. package/pi.dev-src/pi-mono/ai/src/utils/validation.ts +324 -0
  73. package/pi.dev-src/pi-mono/ai/test/abort.test.ts +260 -0
  74. package/pi.dev-src/pi-mono/ai/test/anthropic-oauth.test.ts +99 -0
  75. package/pi.dev-src/pi-mono/ai/test/anthropic-opus-4-7-smoke.test.ts +72 -0
  76. package/pi.dev-src/pi-mono/ai/test/anthropic-sse-parsing.test.ts +113 -0
  77. package/pi.dev-src/pi-mono/ai/test/anthropic-thinking-disable.test.ts +152 -0
  78. package/pi.dev-src/pi-mono/ai/test/anthropic-tool-name-normalization.test.ts +205 -0
  79. package/pi.dev-src/pi-mono/ai/test/azure-utils.ts +28 -0
  80. package/pi.dev-src/pi-mono/ai/test/bedrock-endpoint-resolution.test.ts +131 -0
  81. package/pi.dev-src/pi-mono/ai/test/bedrock-models.test.ts +66 -0
  82. package/pi.dev-src/pi-mono/ai/test/bedrock-thinking-payload.test.ts +107 -0
  83. package/pi.dev-src/pi-mono/ai/test/bedrock-utils.ts +18 -0
  84. package/pi.dev-src/pi-mono/ai/test/cache-retention.test.ts +335 -0
  85. package/pi.dev-src/pi-mono/ai/test/context-overflow.test.ts +714 -0
  86. package/pi.dev-src/pi-mono/ai/test/cross-provider-handoff.test.ts +458 -0
  87. package/pi.dev-src/pi-mono/ai/test/data/red-circle.png +0 -0
  88. package/pi.dev-src/pi-mono/ai/test/empty.test.ts +742 -0
  89. package/pi.dev-src/pi-mono/ai/test/faux-provider.test.ts +597 -0
  90. package/pi.dev-src/pi-mono/ai/test/fireworks-models.test.ts +49 -0
  91. package/pi.dev-src/pi-mono/ai/test/github-copilot-anthropic.test.ts +108 -0
  92. package/pi.dev-src/pi-mono/ai/test/github-copilot-oauth.test.ts +196 -0
  93. package/pi.dev-src/pi-mono/ai/test/google-gemini-cli-claude-thinking-header.test.ts +103 -0
  94. package/pi.dev-src/pi-mono/ai/test/google-gemini-cli-empty-stream.test.ts +108 -0
  95. package/pi.dev-src/pi-mono/ai/test/google-gemini-cli-retry-delay.test.ts +53 -0
  96. package/pi.dev-src/pi-mono/ai/test/google-shared-convert-tools.test.ts +187 -0
  97. package/pi.dev-src/pi-mono/ai/test/google-shared-gemini3-unsigned-tool-call.test.ts +172 -0
  98. package/pi.dev-src/pi-mono/ai/test/google-shared-image-tool-result-routing.test.ts +124 -0
  99. package/pi.dev-src/pi-mono/ai/test/google-thinking-disable.test.ts +183 -0
  100. package/pi.dev-src/pi-mono/ai/test/google-thinking-signature.test.ts +38 -0
  101. package/pi.dev-src/pi-mono/ai/test/google-tool-call-missing-args.test.ts +105 -0
  102. package/pi.dev-src/pi-mono/ai/test/google-vertex-api-key-resolution.test.ts +144 -0
  103. package/pi.dev-src/pi-mono/ai/test/image-tool-result.test.ts +481 -0
  104. package/pi.dev-src/pi-mono/ai/test/interleaved-thinking.test.ts +145 -0
  105. package/pi.dev-src/pi-mono/ai/test/lazy-module-load.test.ts +102 -0
  106. package/pi.dev-src/pi-mono/ai/test/mistral-reasoning-mode.test.ts +66 -0
  107. package/pi.dev-src/pi-mono/ai/test/mistral-tool-schema.test.ts +61 -0
  108. package/pi.dev-src/pi-mono/ai/test/oauth.ts +89 -0
  109. package/pi.dev-src/pi-mono/ai/test/openai-codex-cache-affinity-e2e.test.ts +36 -0
  110. package/pi.dev-src/pi-mono/ai/test/openai-codex-stream.test.ts +686 -0
  111. package/pi.dev-src/pi-mono/ai/test/openai-completions-cache-control-format.test.ts +189 -0
  112. package/pi.dev-src/pi-mono/ai/test/openai-completions-prompt-cache.test.ts +198 -0
  113. package/pi.dev-src/pi-mono/ai/test/openai-completions-thinking-as-text.test.ts +214 -0
  114. package/pi.dev-src/pi-mono/ai/test/openai-completions-tool-choice.test.ts +560 -0
  115. package/pi.dev-src/pi-mono/ai/test/openai-completions-tool-result-images.test.ts +101 -0
  116. package/pi.dev-src/pi-mono/ai/test/openai-responses-cache-affinity-e2e.test.ts +32 -0
  117. package/pi.dev-src/pi-mono/ai/test/openai-responses-copilot-provider.test.ts +128 -0
  118. package/pi.dev-src/pi-mono/ai/test/openai-responses-foreign-toolcall-id.test.ts +66 -0
  119. package/pi.dev-src/pi-mono/ai/test/openai-responses-partial-json-cleanup.test.ts +101 -0
  120. package/pi.dev-src/pi-mono/ai/test/openai-responses-reasoning-replay-e2e.test.ts +292 -0
  121. package/pi.dev-src/pi-mono/ai/test/openai-responses-tool-result-images.test.ts +200 -0
  122. package/pi.dev-src/pi-mono/ai/test/openrouter-cache-write-repro.test.ts +78 -0
  123. package/pi.dev-src/pi-mono/ai/test/overflow.test.ts +64 -0
  124. package/pi.dev-src/pi-mono/ai/test/responseid.test.ts +145 -0
  125. package/pi.dev-src/pi-mono/ai/test/stream.test.ts +1405 -0
  126. package/pi.dev-src/pi-mono/ai/test/supports-xhigh.test.ts +34 -0
  127. package/pi.dev-src/pi-mono/ai/test/tokens.test.ts +304 -0
  128. package/pi.dev-src/pi-mono/ai/test/tool-call-id-normalization.test.ts +291 -0
  129. package/pi.dev-src/pi-mono/ai/test/tool-call-without-result.test.ts +313 -0
  130. package/pi.dev-src/pi-mono/ai/test/total-tokens.test.ts +695 -0
  131. package/pi.dev-src/pi-mono/ai/test/transform-messages-copilot-openai-to-anthropic.test.ts +191 -0
  132. package/pi.dev-src/pi-mono/ai/test/unicode-surrogate.test.ts +754 -0
  133. package/pi.dev-src/pi-mono/ai/test/validation.test.ts +116 -0
  134. package/pi.dev-src/pi-mono/ai/test/xhigh.test.ts +71 -0
  135. package/pi.dev-src/pi-mono/ai/test/zen.test.ts +25 -0
  136. package/pi.dev-src/pi-mono/ai/vitest.config.ts +9 -0
  137. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/antigravity-image-gen.ts +418 -0
  138. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/auto-commit-on-exit.ts +49 -0
  139. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/bash-spawn-hook.ts +30 -0
  140. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/bookmark.ts +50 -0
  141. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/built-in-tool-renderer.ts +249 -0
  142. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/claude-rules.ts +86 -0
  143. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/commands.ts +72 -0
  144. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/confirm-destructive.ts +59 -0
  145. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-compaction.ts +127 -0
  146. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-footer.ts +64 -0
  147. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-header.ts +73 -0
  148. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  149. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  150. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  151. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  152. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
  153. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dirty-repo-guard.ts +56 -0
  154. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom/build.sh +152 -0
  155. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  156. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom-component.ts +132 -0
  157. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  158. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  159. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/index.ts +74 -0
  160. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  161. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/SKILL.md +8 -0
  162. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/dynamic.json +79 -0
  163. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/dynamic.md +5 -0
  164. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-resources/index.ts +15 -0
  165. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/dynamic-tools.ts +74 -0
  166. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/event-bus.ts +43 -0
  167. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/file-trigger.ts +41 -0
  168. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/git-checkpoint.ts +53 -0
  169. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/github-issue-autocomplete.ts +185 -0
  170. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/handoff.ts +153 -0
  171. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/hello.ts +26 -0
  172. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/hidden-thinking-label.ts +53 -0
  173. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/inline-bash.ts +94 -0
  174. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/input-transform.ts +43 -0
  175. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/interactive-shell.ts +196 -0
  176. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/mac-system-theme.ts +47 -0
  177. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/message-renderer.ts +59 -0
  178. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/minimal-mode.ts +426 -0
  179. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/modal-editor.ts +85 -0
  180. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/model-status.ts +31 -0
  181. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/notify.ts +55 -0
  182. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/overlay-qa-tests.ts +1348 -0
  183. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/overlay-test.ts +150 -0
  184. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/permission-gate.ts +34 -0
  185. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/pirate.ts +47 -0
  186. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/plan-mode/index.ts +340 -0
  187. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/plan-mode/utils.ts +168 -0
  188. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/preset.ts +430 -0
  189. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/prompt-customizer.ts +97 -0
  190. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/protected-paths.ts +30 -0
  191. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/provider-payload.ts +18 -0
  192. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/qna.ts +122 -0
  193. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/question.ts +264 -0
  194. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/questionnaire.ts +427 -0
  195. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/rainbow-editor.ts +88 -0
  196. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/reload-runtime.ts +37 -0
  197. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/rpc-demo.ts +118 -0
  198. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/sandbox/index.ts +321 -0
  199. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/sandbox/package-lock.json +92 -0
  200. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/send-user-message.ts +97 -0
  201. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/session-name.ts +27 -0
  202. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/shutdown-command.ts +63 -0
  203. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/snake.ts +343 -0
  204. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/space-invaders.ts +560 -0
  205. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/ssh.ts +220 -0
  206. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/status-line.ts +32 -0
  207. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/structured-output.ts +65 -0
  208. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/planner.md +37 -0
  209. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/reviewer.md +35 -0
  210. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/scout.md +50 -0
  211. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents/worker.md +24 -0
  212. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/agents.ts +126 -0
  213. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/index.ts +987 -0
  214. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  215. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/prompts/implement.md +10 -0
  216. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  217. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/summarize.ts +206 -0
  218. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/system-prompt-header.ts +17 -0
  219. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/tic-tac-toe.ts +1008 -0
  220. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/timed-confirm.ts +70 -0
  221. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/titlebar-spinner.ts +58 -0
  222. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/todo.ts +297 -0
  223. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/tool-override.ts +144 -0
  224. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/tools.ts +141 -0
  225. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/trigger-compact.ts +50 -0
  226. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/truncated-tool.ts +195 -0
  227. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/widget-placement.ts +9 -0
  228. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/with-deps/index.ts +32 -0
  229. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/with-deps/package-lock.json +31 -0
  230. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/working-indicator.ts +123 -0
  231. package/pi.dev-src/pi-mono/coding-agent/examples/extensions/working-message-test.ts +25 -0
  232. package/pi.dev-src/pi-mono/coding-agent/examples/rpc-extension-ui.ts +632 -0
  233. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/01-minimal.ts +22 -0
  234. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/02-custom-model.ts +49 -0
  235. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/03-custom-prompt.ts +62 -0
  236. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/04-skills.ts +55 -0
  237. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/05-tools.ts +44 -0
  238. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/06-extensions.ts +90 -0
  239. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/07-context-files.ts +42 -0
  240. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/08-prompt-templates.ts +51 -0
  241. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  242. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/10-settings.ts +53 -0
  243. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/11-sessions.ts +48 -0
  244. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/12-full-control.ts +73 -0
  245. package/pi.dev-src/pi-mono/coding-agent/examples/sdk/13-session-runtime.ts +67 -0
  246. package/pi.dev-src/pi-mono/coding-agent/scripts/migrate-sessions.sh +93 -0
  247. package/pi.dev-src/pi-mono/coding-agent/src/bun/cli.ts +6 -0
  248. package/pi.dev-src/pi-mono/coding-agent/src/bun/register-bedrock.ts +4 -0
  249. package/pi.dev-src/pi-mono/coding-agent/src/cli/args.ts +335 -0
  250. package/pi.dev-src/pi-mono/coding-agent/src/cli/config-selector.ts +52 -0
  251. package/pi.dev-src/pi-mono/coding-agent/src/cli/file-processor.ts +100 -0
  252. package/pi.dev-src/pi-mono/coding-agent/src/cli/initial-message.ts +43 -0
  253. package/pi.dev-src/pi-mono/coding-agent/src/cli/list-models.ts +110 -0
  254. package/pi.dev-src/pi-mono/coding-agent/src/cli/session-picker.ts +52 -0
  255. package/pi.dev-src/pi-mono/coding-agent/src/cli.ts +17 -0
  256. package/pi.dev-src/pi-mono/coding-agent/src/config.ts +261 -0
  257. package/pi.dev-src/pi-mono/coding-agent/src/core/agent-session-runtime.ts +394 -0
  258. package/pi.dev-src/pi-mono/coding-agent/src/core/agent-session-services.ts +196 -0
  259. package/pi.dev-src/pi-mono/coding-agent/src/core/agent-session.ts +3096 -0
  260. package/pi.dev-src/pi-mono/coding-agent/src/core/auth-storage.ts +493 -0
  261. package/pi.dev-src/pi-mono/coding-agent/src/core/bash-executor.ts +154 -0
  262. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/branch-summarization.ts +355 -0
  263. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/compaction.ts +839 -0
  264. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/index.ts +7 -0
  265. package/pi.dev-src/pi-mono/coding-agent/src/core/compaction/utils.ts +170 -0
  266. package/pi.dev-src/pi-mono/coding-agent/src/core/defaults.ts +3 -0
  267. package/pi.dev-src/pi-mono/coding-agent/src/core/diagnostics.ts +15 -0
  268. package/pi.dev-src/pi-mono/coding-agent/src/core/event-bus.ts +33 -0
  269. package/pi.dev-src/pi-mono/coding-agent/src/core/exec.ts +107 -0
  270. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/ansi-to-html.ts +258 -0
  271. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/index.ts +314 -0
  272. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/template.css +1017 -0
  273. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/template.html +55 -0
  274. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/template.js +1770 -0
  275. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/tool-renderer.ts +158 -0
  276. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/vendor/highlight.min.js +1213 -0
  277. package/pi.dev-src/pi-mono/coding-agent/src/core/export-html/vendor/marked.min.js +6 -0
  278. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/index.ts +171 -0
  279. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/loader.ts +606 -0
  280. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/runner.ts +1019 -0
  281. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/types.ts +1542 -0
  282. package/pi.dev-src/pi-mono/coding-agent/src/core/extensions/wrapper.ts +30 -0
  283. package/pi.dev-src/pi-mono/coding-agent/src/core/footer-data-provider.ts +354 -0
  284. package/pi.dev-src/pi-mono/coding-agent/src/core/index.ts +77 -0
  285. package/pi.dev-src/pi-mono/coding-agent/src/core/keybindings.ts +370 -0
  286. package/pi.dev-src/pi-mono/coding-agent/src/core/messages.ts +195 -0
  287. package/pi.dev-src/pi-mono/coding-agent/src/core/model-registry.ts +858 -0
  288. package/pi.dev-src/pi-mono/coding-agent/src/core/model-resolver.ts +629 -0
  289. package/pi.dev-src/pi-mono/coding-agent/src/core/output-guard.ts +74 -0
  290. package/pi.dev-src/pi-mono/coding-agent/src/core/package-manager.ts +2408 -0
  291. package/pi.dev-src/pi-mono/coding-agent/src/core/prompt-templates.ts +296 -0
  292. package/pi.dev-src/pi-mono/coding-agent/src/core/resolve-config-value.ts +142 -0
  293. package/pi.dev-src/pi-mono/coding-agent/src/core/resource-loader.ts +917 -0
  294. package/pi.dev-src/pi-mono/coding-agent/src/core/sdk.ts +380 -0
  295. package/pi.dev-src/pi-mono/coding-agent/src/core/session-cwd.ts +59 -0
  296. package/pi.dev-src/pi-mono/coding-agent/src/core/session-manager.ts +1425 -0
  297. package/pi.dev-src/pi-mono/coding-agent/src/core/settings-manager.ts +999 -0
  298. package/pi.dev-src/pi-mono/coding-agent/src/core/skills.ts +508 -0
  299. package/pi.dev-src/pi-mono/coding-agent/src/core/slash-commands.ts +39 -0
  300. package/pi.dev-src/pi-mono/coding-agent/src/core/source-info.ts +40 -0
  301. package/pi.dev-src/pi-mono/coding-agent/src/core/system-prompt.ts +172 -0
  302. package/pi.dev-src/pi-mono/coding-agent/src/core/telemetry.ts +13 -0
  303. package/pi.dev-src/pi-mono/coding-agent/src/core/timings.ts +31 -0
  304. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/bash.ts +448 -0
  305. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/edit-diff.ts +445 -0
  306. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/edit.ts +487 -0
  307. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/file-mutation-queue.ts +39 -0
  308. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/find.ts +370 -0
  309. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/grep.ts +384 -0
  310. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/index.ts +196 -0
  311. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/ls.ts +229 -0
  312. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/path-utils.ts +94 -0
  313. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/read.ts +273 -0
  314. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/render-utils.ts +64 -0
  315. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/tool-definition-wrapper.ts +45 -0
  316. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/truncate.ts +265 -0
  317. package/pi.dev-src/pi-mono/coding-agent/src/core/tools/write.ts +281 -0
  318. package/pi.dev-src/pi-mono/coding-agent/src/index.ts +352 -0
  319. package/pi.dev-src/pi-mono/coding-agent/src/main.ts +731 -0
  320. package/pi.dev-src/pi-mono/coding-agent/src/migrations.ts +314 -0
  321. package/pi.dev-src/pi-mono/coding-agent/src/modes/index.ts +9 -0
  322. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/assets/clankolas.png +0 -0
  323. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/armin.ts +382 -0
  324. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/assistant-message.ts +147 -0
  325. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/bash-execution.ts +218 -0
  326. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/bordered-loader.ts +68 -0
  327. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/branch-summary-message.ts +58 -0
  328. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/compaction-summary-message.ts +59 -0
  329. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/config-selector.ts +592 -0
  330. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/countdown-timer.ts +38 -0
  331. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/custom-editor.ts +80 -0
  332. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/custom-message.ts +99 -0
  333. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/daxnuts.ts +164 -0
  334. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/diff.ts +147 -0
  335. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/dynamic-border.ts +25 -0
  336. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/earendil-announcement.ts +53 -0
  337. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/extension-editor.ts +147 -0
  338. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/extension-input.ts +87 -0
  339. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/extension-selector.ts +107 -0
  340. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/footer.ts +220 -0
  341. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/index.ts +32 -0
  342. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/keybinding-hints.ts +24 -0
  343. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/login-dialog.ts +178 -0
  344. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/model-selector.ts +338 -0
  345. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/oauth-selector.ts +121 -0
  346. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/scoped-models-selector.ts +355 -0
  347. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/session-selector-search.ts +194 -0
  348. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/session-selector.ts +1026 -0
  349. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/settings-selector.ts +456 -0
  350. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/show-images-selector.ts +50 -0
  351. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/skill-invocation-message.ts +55 -0
  352. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/theme-selector.ts +67 -0
  353. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/thinking-selector.ts +74 -0
  354. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/tool-execution.ts +352 -0
  355. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/tree-selector.ts +1246 -0
  356. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/user-message-selector.ts +155 -0
  357. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/user-message.ts +35 -0
  358. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/components/visual-truncate.ts +50 -0
  359. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/interactive-mode.ts +5155 -0
  360. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/dark.json +85 -0
  361. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/light.json +84 -0
  362. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/theme-schema.json +335 -0
  363. package/pi.dev-src/pi-mono/coding-agent/src/modes/interactive/theme/theme.ts +1141 -0
  364. package/pi.dev-src/pi-mono/coding-agent/src/modes/print-mode.ts +158 -0
  365. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/jsonl.ts +58 -0
  366. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/rpc-client.ts +515 -0
  367. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/rpc-mode.ts +745 -0
  368. package/pi.dev-src/pi-mono/coding-agent/src/modes/rpc/rpc-types.ts +264 -0
  369. package/pi.dev-src/pi-mono/coding-agent/src/package-manager-cli.ts +270 -0
  370. package/pi.dev-src/pi-mono/coding-agent/src/utils/changelog.ts +99 -0
  371. package/pi.dev-src/pi-mono/coding-agent/src/utils/child-process.ts +86 -0
  372. package/pi.dev-src/pi-mono/coding-agent/src/utils/clipboard-image.ts +300 -0
  373. package/pi.dev-src/pi-mono/coding-agent/src/utils/clipboard-native.ts +22 -0
  374. package/pi.dev-src/pi-mono/coding-agent/src/utils/clipboard.ts +81 -0
  375. package/pi.dev-src/pi-mono/coding-agent/src/utils/exif-orientation.ts +183 -0
  376. package/pi.dev-src/pi-mono/coding-agent/src/utils/frontmatter.ts +39 -0
  377. package/pi.dev-src/pi-mono/coding-agent/src/utils/fs-watch.ts +30 -0
  378. package/pi.dev-src/pi-mono/coding-agent/src/utils/git.ts +192 -0
  379. package/pi.dev-src/pi-mono/coding-agent/src/utils/image-convert.ts +41 -0
  380. package/pi.dev-src/pi-mono/coding-agent/src/utils/image-resize.ts +176 -0
  381. package/pi.dev-src/pi-mono/coding-agent/src/utils/mime.ts +30 -0
  382. package/pi.dev-src/pi-mono/coding-agent/src/utils/paths.ts +20 -0
  383. package/pi.dev-src/pi-mono/coding-agent/src/utils/photon.ts +139 -0
  384. package/pi.dev-src/pi-mono/coding-agent/src/utils/shell.ts +210 -0
  385. package/pi.dev-src/pi-mono/coding-agent/src/utils/sleep.ts +18 -0
  386. package/pi.dev-src/pi-mono/coding-agent/src/utils/tools-manager.ts +287 -0
  387. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-auto-compaction-queue.test.ts +437 -0
  388. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-branching.test.ts +156 -0
  389. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-compaction.test.ts +208 -0
  390. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-concurrent.test.ts +618 -0
  391. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-dynamic-provider.test.ts +117 -0
  392. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-dynamic-tools.test.ts +182 -0
  393. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-retry.test.ts +318 -0
  394. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-runtime-events.test.ts +208 -0
  395. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-stats.test.ts +143 -0
  396. package/pi.dev-src/pi-mono/coding-agent/test/agent-session-tree-navigation.test.ts +323 -0
  397. package/pi.dev-src/pi-mono/coding-agent/test/args.test.ts +328 -0
  398. package/pi.dev-src/pi-mono/coding-agent/test/assistant-message.test.ts +57 -0
  399. package/pi.dev-src/pi-mono/coding-agent/test/auth-storage.test.ts +462 -0
  400. package/pi.dev-src/pi-mono/coding-agent/test/bash-close-hang-windows.test.ts +126 -0
  401. package/pi.dev-src/pi-mono/coding-agent/test/bash-execution-width.test.ts +80 -0
  402. package/pi.dev-src/pi-mono/coding-agent/test/block-images.test.ts +120 -0
  403. package/pi.dev-src/pi-mono/coding-agent/test/clipboard-image-bmp-conversion.test.ts +88 -0
  404. package/pi.dev-src/pi-mono/coding-agent/test/clipboard-image.test.ts +136 -0
  405. package/pi.dev-src/pi-mono/coding-agent/test/compaction-extensions-example.test.ts +66 -0
  406. package/pi.dev-src/pi-mono/coding-agent/test/compaction-extensions.test.ts +415 -0
  407. package/pi.dev-src/pi-mono/coding-agent/test/compaction-serialization.test.ts +79 -0
  408. package/pi.dev-src/pi-mono/coding-agent/test/compaction-summary-reasoning.test.ts +118 -0
  409. package/pi.dev-src/pi-mono/coding-agent/test/compaction-thinking-model.test.ts +223 -0
  410. package/pi.dev-src/pi-mono/coding-agent/test/compaction.test.ts +550 -0
  411. package/pi.dev-src/pi-mono/coding-agent/test/config.test.ts +30 -0
  412. package/pi.dev-src/pi-mono/coding-agent/test/edit-tool-legacy-input.test.ts +116 -0
  413. package/pi.dev-src/pi-mono/coding-agent/test/edit-tool-no-full-redraw.test.ts +235 -0
  414. package/pi.dev-src/pi-mono/coding-agent/test/export-html-whitespace.test.ts +12 -0
  415. package/pi.dev-src/pi-mono/coding-agent/test/export-html-xss.test.ts +28 -0
  416. package/pi.dev-src/pi-mono/coding-agent/test/extensions-discovery.test.ts +463 -0
  417. package/pi.dev-src/pi-mono/coding-agent/test/extensions-input-event.test.ts +112 -0
  418. package/pi.dev-src/pi-mono/coding-agent/test/extensions-runner.test.ts +805 -0
  419. package/pi.dev-src/pi-mono/coding-agent/test/file-mutation-queue.test.ts +163 -0
  420. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/assistant-message-with-thinking-code.json +33 -0
  421. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/before-compaction.jsonl +1003 -0
  422. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/empty-agent/.gitkeep +0 -0
  423. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/empty-cwd/.gitkeep +0 -0
  424. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/large-session.jsonl +1019 -0
  425. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/consecutive-hyphens/SKILL.md +8 -0
  426. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/disable-model-invocation/SKILL.md +9 -0
  427. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/invalid-name-chars/SKILL.md +8 -0
  428. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/invalid-yaml/SKILL.md +8 -0
  429. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/long-name/SKILL.md +8 -0
  430. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/missing-description/SKILL.md +7 -0
  431. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/multiline-description/SKILL.md +11 -0
  432. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/name-mismatch/SKILL.md +8 -0
  433. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/nested/child-skill/SKILL.md +8 -0
  434. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/no-frontmatter/SKILL.md +3 -0
  435. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/root-skill-preferred/SKILL.md +3 -0
  436. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/root-skill-preferred/nested-child/SKILL.md +3 -0
  437. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/unknown-field/SKILL.md +10 -0
  438. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills/valid-skill/SKILL.md +8 -0
  439. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills-collision/first/calendar/SKILL.md +8 -0
  440. package/pi.dev-src/pi-mono/coding-agent/test/fixtures/skills-collision/second/calendar/SKILL.md +8 -0
  441. package/pi.dev-src/pi-mono/coding-agent/test/footer-data-provider.test.ts +265 -0
  442. package/pi.dev-src/pi-mono/coding-agent/test/footer-width.test.ts +115 -0
  443. package/pi.dev-src/pi-mono/coding-agent/test/frontmatter.test.ts +60 -0
  444. package/pi.dev-src/pi-mono/coding-agent/test/git-ssh-url.test.ts +78 -0
  445. package/pi.dev-src/pi-mono/coding-agent/test/git-update.test.ts +411 -0
  446. package/pi.dev-src/pi-mono/coding-agent/test/image-processing.test.ts +145 -0
  447. package/pi.dev-src/pi-mono/coding-agent/test/image-resize-callers.test.ts +53 -0
  448. package/pi.dev-src/pi-mono/coding-agent/test/initial-message.test.ts +48 -0
  449. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-anthropic-warning.test.ts +73 -0
  450. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-clone-command.test.ts +77 -0
  451. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-compaction.test.ts +57 -0
  452. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-import-command.test.ts +144 -0
  453. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-status.test.ts +635 -0
  454. package/pi.dev-src/pi-mono/coding-agent/test/interactive-mode-suspend.test.ts +149 -0
  455. package/pi.dev-src/pi-mono/coding-agent/test/keybindings-migration.test.ts +88 -0
  456. package/pi.dev-src/pi-mono/coding-agent/test/model-registry.test.ts +1209 -0
  457. package/pi.dev-src/pi-mono/coding-agent/test/model-resolver.test.ts +436 -0
  458. package/pi.dev-src/pi-mono/coding-agent/test/package-command-paths.test.ts +144 -0
  459. package/pi.dev-src/pi-mono/coding-agent/test/package-manager-ssh.test.ts +97 -0
  460. package/pi.dev-src/pi-mono/coding-agent/test/package-manager.test.ts +1795 -0
  461. package/pi.dev-src/pi-mono/coding-agent/test/path-utils.test.ts +162 -0
  462. package/pi.dev-src/pi-mono/coding-agent/test/plan-mode-utils.test.ts +261 -0
  463. package/pi.dev-src/pi-mono/coding-agent/test/print-mode.test.ts +140 -0
  464. package/pi.dev-src/pi-mono/coding-agent/test/prompt-templates.test.ts +515 -0
  465. package/pi.dev-src/pi-mono/coding-agent/test/resource-loader.test.ts +576 -0
  466. package/pi.dev-src/pi-mono/coding-agent/test/rpc-client-clone.test.ts +29 -0
  467. package/pi.dev-src/pi-mono/coding-agent/test/rpc-example.ts +86 -0
  468. package/pi.dev-src/pi-mono/coding-agent/test/rpc-jsonl.test.ts +65 -0
  469. package/pi.dev-src/pi-mono/coding-agent/test/rpc-prompt-response-semantics.test.ts +285 -0
  470. package/pi.dev-src/pi-mono/coding-agent/test/rpc.test.ts +321 -0
  471. package/pi.dev-src/pi-mono/coding-agent/test/sdk-codex-cache-probe-tool-loop.ts +364 -0
  472. package/pi.dev-src/pi-mono/coding-agent/test/sdk-openrouter-attribution.test.ts +181 -0
  473. package/pi.dev-src/pi-mono/coding-agent/test/sdk-session-manager.test.ts +95 -0
  474. package/pi.dev-src/pi-mono/coding-agent/test/sdk-skills.test.ts +109 -0
  475. package/pi.dev-src/pi-mono/coding-agent/test/session-cwd.test.ts +91 -0
  476. package/pi.dev-src/pi-mono/coding-agent/test/session-info-modified-timestamp.test.ts +83 -0
  477. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/build-context.test.ts +268 -0
  478. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/custom-session-id.test.ts +109 -0
  479. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/file-operations.test.ts +208 -0
  480. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/labels.test.ts +198 -0
  481. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/migration.test.ts +78 -0
  482. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/save-entry.test.ts +55 -0
  483. package/pi.dev-src/pi-mono/coding-agent/test/session-manager/tree-traversal.test.ts +533 -0
  484. package/pi.dev-src/pi-mono/coding-agent/test/session-selector-path-delete.test.ts +315 -0
  485. package/pi.dev-src/pi-mono/coding-agent/test/session-selector-rename.test.ts +111 -0
  486. package/pi.dev-src/pi-mono/coding-agent/test/session-selector-search.test.ts +195 -0
  487. package/pi.dev-src/pi-mono/coding-agent/test/settings-manager-bug.test.ts +147 -0
  488. package/pi.dev-src/pi-mono/coding-agent/test/settings-manager.test.ts +319 -0
  489. package/pi.dev-src/pi-mono/coding-agent/test/skills.test.ts +432 -0
  490. package/pi.dev-src/pi-mono/coding-agent/test/stdout-cleanliness.test.ts +103 -0
  491. package/pi.dev-src/pi-mono/coding-agent/test/streaming-render-debug.ts +97 -0
  492. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-bash-persistence.test.ts +242 -0
  493. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-compaction.test.ts +343 -0
  494. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-model-extension.test.ts +325 -0
  495. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-prompt.test.ts +323 -0
  496. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-queue.test.ts +422 -0
  497. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-retry-events.test.ts +358 -0
  498. package/pi.dev-src/pi-mono/coding-agent/test/suite/agent-session-runtime.test.ts +553 -0
  499. package/pi.dev-src/pi-mono/coding-agent/test/suite/harness.ts +208 -0
  500. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2023-queued-slash-command-followup.test.ts +80 -0
  501. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2753-reload-stale-resource-settings.test.ts +100 -0
  502. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2781-skill-collision-precedence.test.ts +120 -0
  503. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2791-fswatch-error-crash.test.ts +106 -0
  504. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2835-tools-allowlist-filters-extension-tools.test.ts +94 -0
  505. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/2860-replaced-session-context.test.ts +274 -0
  506. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3217-scoped-model-order.test.ts +104 -0
  507. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3302-find-path-glob.test.ts +72 -0
  508. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3303-find-nested-gitignore.test.ts +83 -0
  509. package/pi.dev-src/pi-mono/coding-agent/test/suite/regressions/3317-network-connection-lost-retry.test.ts +33 -0
  510. package/pi.dev-src/pi-mono/coding-agent/test/system-prompt.test.ts +102 -0
  511. package/pi.dev-src/pi-mono/coding-agent/test/test-harness.test.ts +321 -0
  512. package/pi.dev-src/pi-mono/coding-agent/test/test-harness.ts +446 -0
  513. package/pi.dev-src/pi-mono/coding-agent/test/test-theme-colors.ts +246 -0
  514. package/pi.dev-src/pi-mono/coding-agent/test/theme-export.test.ts +104 -0
  515. package/pi.dev-src/pi-mono/coding-agent/test/tool-execution-component.test.ts +331 -0
  516. package/pi.dev-src/pi-mono/coding-agent/test/tools.test.ts +889 -0
  517. package/pi.dev-src/pi-mono/coding-agent/test/tree-selector.test.ts +655 -0
  518. package/pi.dev-src/pi-mono/coding-agent/test/trigger-compact-extension.test.ts +57 -0
  519. package/pi.dev-src/pi-mono/coding-agent/test/truncate-to-width.test.ts +81 -0
  520. package/pi.dev-src/pi-mono/coding-agent/test/user-message.test.ts +25 -0
  521. package/pi.dev-src/pi-mono/coding-agent/test/utilities.ts +316 -0
  522. package/pi.dev-src/pi-mono/coding-agent/tsconfig.examples.json +16 -0
  523. package/pi.dev-src/pi-mono/coding-agent/vitest.config.ts +26 -0
  524. package/pi.dev-src/pi-mono/mom/dev.sh +30 -0
  525. package/pi.dev-src/pi-mono/mom/docker.sh +95 -0
  526. package/pi.dev-src/pi-mono/mom/scripts/migrate-timestamps.ts +121 -0
  527. package/pi.dev-src/pi-mono/mom/src/agent.ts +882 -0
  528. package/pi.dev-src/pi-mono/mom/src/context.ts +180 -0
  529. package/pi.dev-src/pi-mono/mom/src/download.ts +117 -0
  530. package/pi.dev-src/pi-mono/mom/src/events.ts +442 -0
  531. package/pi.dev-src/pi-mono/mom/src/fs-watch.ts +30 -0
  532. package/pi.dev-src/pi-mono/mom/src/log.ts +271 -0
  533. package/pi.dev-src/pi-mono/mom/src/main.ts +367 -0
  534. package/pi.dev-src/pi-mono/mom/src/sandbox.ts +221 -0
  535. package/pi.dev-src/pi-mono/mom/src/slack.ts +623 -0
  536. package/pi.dev-src/pi-mono/mom/src/store.ts +234 -0
  537. package/pi.dev-src/pi-mono/mom/src/tools/attach.ts +47 -0
  538. package/pi.dev-src/pi-mono/mom/src/tools/bash.ts +97 -0
  539. package/pi.dev-src/pi-mono/mom/src/tools/edit.ts +165 -0
  540. package/pi.dev-src/pi-mono/mom/src/tools/index.ts +19 -0
  541. package/pi.dev-src/pi-mono/mom/src/tools/read.ts +159 -0
  542. package/pi.dev-src/pi-mono/mom/src/tools/truncate.ts +236 -0
  543. package/pi.dev-src/pi-mono/mom/src/tools/write.ts +45 -0
  544. package/pi.dev-src/pi-mono/mom/test/events.test.ts +50 -0
  545. package/pi.dev-src/pi-mono/pods/scripts/model_run.sh +83 -0
  546. package/pi.dev-src/pi-mono/pods/scripts/pod_setup.sh +336 -0
  547. package/pi.dev-src/pi-mono/pods/src/cli.ts +360 -0
  548. package/pi.dev-src/pi-mono/pods/src/commands/models.ts +753 -0
  549. package/pi.dev-src/pi-mono/pods/src/commands/pods.ts +205 -0
  550. package/pi.dev-src/pi-mono/pods/src/commands/prompt.ts +84 -0
  551. package/pi.dev-src/pi-mono/pods/src/config.ts +80 -0
  552. package/pi.dev-src/pi-mono/pods/src/index.ts +2 -0
  553. package/pi.dev-src/pi-mono/pods/src/model-configs.ts +111 -0
  554. package/pi.dev-src/pi-mono/pods/src/models.json +295 -0
  555. package/pi.dev-src/pi-mono/pods/src/ssh.ts +151 -0
  556. package/pi.dev-src/pi-mono/pods/src/types.ts +27 -0
  557. package/pi.dev-src/pi-mono/tui/src/autocomplete.ts +783 -0
  558. package/pi.dev-src/pi-mono/tui/src/components/box.ts +137 -0
  559. package/pi.dev-src/pi-mono/tui/src/components/cancellable-loader.ts +40 -0
  560. package/pi.dev-src/pi-mono/tui/src/components/editor.ts +2280 -0
  561. package/pi.dev-src/pi-mono/tui/src/components/image.ts +104 -0
  562. package/pi.dev-src/pi-mono/tui/src/components/input.ts +503 -0
  563. package/pi.dev-src/pi-mono/tui/src/components/loader.ts +86 -0
  564. package/pi.dev-src/pi-mono/tui/src/components/markdown.ts +852 -0
  565. package/pi.dev-src/pi-mono/tui/src/components/select-list.ts +229 -0
  566. package/pi.dev-src/pi-mono/tui/src/components/settings-list.ts +250 -0
  567. package/pi.dev-src/pi-mono/tui/src/components/spacer.ts +28 -0
  568. package/pi.dev-src/pi-mono/tui/src/components/text.ts +106 -0
  569. package/pi.dev-src/pi-mono/tui/src/components/truncated-text.ts +65 -0
  570. package/pi.dev-src/pi-mono/tui/src/editor-component.ts +74 -0
  571. package/pi.dev-src/pi-mono/tui/src/fuzzy.ts +133 -0
  572. package/pi.dev-src/pi-mono/tui/src/index.ts +106 -0
  573. package/pi.dev-src/pi-mono/tui/src/keybindings.ts +244 -0
  574. package/pi.dev-src/pi-mono/tui/src/keys.ts +1400 -0
  575. package/pi.dev-src/pi-mono/tui/src/kill-ring.ts +46 -0
  576. package/pi.dev-src/pi-mono/tui/src/stdin-buffer.ts +386 -0
  577. package/pi.dev-src/pi-mono/tui/src/terminal-image.ts +414 -0
  578. package/pi.dev-src/pi-mono/tui/src/terminal.ts +373 -0
  579. package/pi.dev-src/pi-mono/tui/src/tui.ts +1243 -0
  580. package/pi.dev-src/pi-mono/tui/src/undo-stack.ts +28 -0
  581. package/pi.dev-src/pi-mono/tui/src/utils.ts +1085 -0
  582. package/pi.dev-src/pi-mono/tui/test/autocomplete.test.ts +542 -0
  583. package/pi.dev-src/pi-mono/tui/test/bug-regression-isimageline-startswith-bug.test.ts +237 -0
  584. package/pi.dev-src/pi-mono/tui/test/chat-simple.ts +129 -0
  585. package/pi.dev-src/pi-mono/tui/test/editor.test.ts +3812 -0
  586. package/pi.dev-src/pi-mono/tui/test/fuzzy.test.ts +98 -0
  587. package/pi.dev-src/pi-mono/tui/test/image-test.ts +56 -0
  588. package/pi.dev-src/pi-mono/tui/test/input.test.ts +580 -0
  589. package/pi.dev-src/pi-mono/tui/test/key-tester.ts +105 -0
  590. package/pi.dev-src/pi-mono/tui/test/keybindings.test.ts +38 -0
  591. package/pi.dev-src/pi-mono/tui/test/keys.test.ts +614 -0
  592. package/pi.dev-src/pi-mono/tui/test/markdown.test.ts +1236 -0
  593. package/pi.dev-src/pi-mono/tui/test/overlay-non-capturing.test.ts +609 -0
  594. package/pi.dev-src/pi-mono/tui/test/overlay-options.test.ts +538 -0
  595. package/pi.dev-src/pi-mono/tui/test/overlay-short-content.test.ts +56 -0
  596. package/pi.dev-src/pi-mono/tui/test/regression-regional-indicator-width.test.ts +52 -0
  597. package/pi.dev-src/pi-mono/tui/test/select-list.test.ts +116 -0
  598. package/pi.dev-src/pi-mono/tui/test/stdin-buffer.test.ts +422 -0
  599. package/pi.dev-src/pi-mono/tui/test/terminal-image.test.ts +279 -0
  600. package/pi.dev-src/pi-mono/tui/test/test-themes.ts +38 -0
  601. package/pi.dev-src/pi-mono/tui/test/truncate-to-width.test.ts +62 -0
  602. package/pi.dev-src/pi-mono/tui/test/truncated-text.test.ts +129 -0
  603. package/pi.dev-src/pi-mono/tui/test/tui-cell-size-input.test.ts +81 -0
  604. package/pi.dev-src/pi-mono/tui/test/tui-overlay-style-leak.test.ts +72 -0
  605. package/pi.dev-src/pi-mono/tui/test/tui-render.test.ts +509 -0
  606. package/pi.dev-src/pi-mono/tui/test/viewport-overwrite-repro.ts +106 -0
  607. package/pi.dev-src/pi-mono/tui/test/virtual-terminal.ts +218 -0
  608. package/pi.dev-src/pi-mono/tui/test/wrap-ansi.test.ts +207 -0
  609. package/pi.dev-src/pi-mono/tui/vitest.config.ts +7 -0
  610. package/pi.dev-src/pi-mono/web-ui/example/index.html +13 -0
  611. package/pi.dev-src/pi-mono/web-ui/example/src/app.css +1 -0
  612. package/pi.dev-src/pi-mono/web-ui/example/src/custom-messages.ts +99 -0
  613. package/pi.dev-src/pi-mono/web-ui/example/src/main.ts +421 -0
  614. package/pi.dev-src/pi-mono/web-ui/example/tsconfig.json +23 -0
  615. package/pi.dev-src/pi-mono/web-ui/example/vite.config.ts +6 -0
  616. package/pi.dev-src/pi-mono/web-ui/scripts/count-prompt-tokens.ts +88 -0
  617. package/pi.dev-src/pi-mono/web-ui/src/ChatPanel.ts +209 -0
  618. package/pi.dev-src/pi-mono/web-ui/src/app.css +68 -0
  619. package/pi.dev-src/pi-mono/web-ui/src/components/AgentInterface.ts +403 -0
  620. package/pi.dev-src/pi-mono/web-ui/src/components/AttachmentTile.ts +107 -0
  621. package/pi.dev-src/pi-mono/web-ui/src/components/ConsoleBlock.ts +72 -0
  622. package/pi.dev-src/pi-mono/web-ui/src/components/CustomProviderCard.ts +100 -0
  623. package/pi.dev-src/pi-mono/web-ui/src/components/ExpandableSection.ts +46 -0
  624. package/pi.dev-src/pi-mono/web-ui/src/components/Input.ts +113 -0
  625. package/pi.dev-src/pi-mono/web-ui/src/components/MessageEditor.ts +405 -0
  626. package/pi.dev-src/pi-mono/web-ui/src/components/MessageList.ts +98 -0
  627. package/pi.dev-src/pi-mono/web-ui/src/components/Messages.ts +383 -0
  628. package/pi.dev-src/pi-mono/web-ui/src/components/ProviderKeyInput.ts +153 -0
  629. package/pi.dev-src/pi-mono/web-ui/src/components/SandboxedIframe.ts +626 -0
  630. package/pi.dev-src/pi-mono/web-ui/src/components/StreamingMessageContainer.ts +103 -0
  631. package/pi.dev-src/pi-mono/web-ui/src/components/ThinkingBlock.ts +43 -0
  632. package/pi.dev-src/pi-mono/web-ui/src/components/message-renderer-registry.ts +28 -0
  633. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts +220 -0
  634. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/AttachmentsRuntimeProvider.ts +66 -0
  635. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/ConsoleRuntimeProvider.ts +186 -0
  636. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/FileDownloadRuntimeProvider.ts +110 -0
  637. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/RuntimeMessageBridge.ts +82 -0
  638. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/RuntimeMessageRouter.ts +216 -0
  639. package/pi.dev-src/pi-mono/web-ui/src/components/sandbox/SandboxRuntimeProvider.ts +52 -0
  640. package/pi.dev-src/pi-mono/web-ui/src/dialogs/ApiKeyPromptDialog.ts +75 -0
  641. package/pi.dev-src/pi-mono/web-ui/src/dialogs/AttachmentOverlay.ts +636 -0
  642. package/pi.dev-src/pi-mono/web-ui/src/dialogs/CustomProviderDialog.ts +274 -0
  643. package/pi.dev-src/pi-mono/web-ui/src/dialogs/ModelSelector.ts +370 -0
  644. package/pi.dev-src/pi-mono/web-ui/src/dialogs/PersistentStorageDialog.ts +144 -0
  645. package/pi.dev-src/pi-mono/web-ui/src/dialogs/ProvidersModelsTab.ts +212 -0
  646. package/pi.dev-src/pi-mono/web-ui/src/dialogs/SessionListDialog.ts +150 -0
  647. package/pi.dev-src/pi-mono/web-ui/src/dialogs/SettingsDialog.ts +218 -0
  648. package/pi.dev-src/pi-mono/web-ui/src/index.ts +120 -0
  649. package/pi.dev-src/pi-mono/web-ui/src/prompts/prompts.ts +282 -0
  650. package/pi.dev-src/pi-mono/web-ui/src/storage/app-storage.ts +60 -0
  651. package/pi.dev-src/pi-mono/web-ui/src/storage/backends/indexeddb-storage-backend.ts +193 -0
  652. package/pi.dev-src/pi-mono/web-ui/src/storage/store.ts +33 -0
  653. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/custom-providers-store.ts +62 -0
  654. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/provider-keys-store.ts +33 -0
  655. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/sessions-store.ts +136 -0
  656. package/pi.dev-src/pi-mono/web-ui/src/storage/stores/settings-store.ts +34 -0
  657. package/pi.dev-src/pi-mono/web-ui/src/storage/types.ts +206 -0
  658. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ArtifactElement.ts +14 -0
  659. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ArtifactPill.ts +26 -0
  660. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/Console.ts +93 -0
  661. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/DocxArtifact.ts +213 -0
  662. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ExcelArtifact.ts +231 -0
  663. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/GenericArtifact.ts +117 -0
  664. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/HtmlArtifact.ts +195 -0
  665. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/ImageArtifact.ts +116 -0
  666. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/MarkdownArtifact.ts +82 -0
  667. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/PdfArtifact.ts +201 -0
  668. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/SvgArtifact.ts +119 -0
  669. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/TextArtifact.ts +148 -0
  670. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/artifacts-tool-renderer.ts +310 -0
  671. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/artifacts.ts +713 -0
  672. package/pi.dev-src/pi-mono/web-ui/src/tools/artifacts/index.ts +7 -0
  673. package/pi.dev-src/pi-mono/web-ui/src/tools/extract-document.ts +275 -0
  674. package/pi.dev-src/pi-mono/web-ui/src/tools/index.ts +46 -0
  675. package/pi.dev-src/pi-mono/web-ui/src/tools/javascript-repl.ts +293 -0
  676. package/pi.dev-src/pi-mono/web-ui/src/tools/renderer-registry.ts +130 -0
  677. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/BashRenderer.ts +52 -0
  678. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/CalculateRenderer.ts +58 -0
  679. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/DefaultRenderer.ts +103 -0
  680. package/pi.dev-src/pi-mono/web-ui/src/tools/renderers/GetCurrentTimeRenderer.ts +92 -0
  681. package/pi.dev-src/pi-mono/web-ui/src/tools/types.ts +15 -0
  682. package/pi.dev-src/pi-mono/web-ui/src/utils/attachment-utils.ts +472 -0
  683. package/pi.dev-src/pi-mono/web-ui/src/utils/auth-token.ts +22 -0
  684. package/pi.dev-src/pi-mono/web-ui/src/utils/format.ts +42 -0
  685. package/pi.dev-src/pi-mono/web-ui/src/utils/i18n.ts +653 -0
  686. package/pi.dev-src/pi-mono/web-ui/src/utils/model-discovery.ts +277 -0
  687. package/pi.dev-src/pi-mono/web-ui/src/utils/proxy-utils.ts +139 -0
  688. package/pi.dev-src/pi-mono/web-ui/src/utils/test-sessions.ts +2357 -0
  689. package/pi.dev-src/pi-mono/web-ui/tsconfig.json +7 -0
  690. package/scripts/lib/extension-debug-harness.ts +3 -10
  691. package/scripts/lib/recording-extension-api.ts +71 -2
  692. package/scripts/pi-usereq-debug.sh +1 -1
  693. package/scripts/tool-args-to-params.ts +4 -15
  694. package/src/cli.ts +24 -68
  695. package/src/core/agent-tool-json.ts +53 -239
  696. package/src/core/compress-payload.ts +4 -74
  697. package/src/core/compress.ts +26 -15
  698. package/src/core/config.ts +468 -42
  699. package/src/core/debug-runtime.ts +542 -0
  700. package/src/core/extension-status.ts +314 -59
  701. package/src/core/find-constructs.ts +3 -3
  702. package/src/core/find-payload.ts +26 -132
  703. package/src/core/path-context.ts +346 -81
  704. package/src/core/pi-notify.ts +115 -5
  705. package/src/core/pi-usereq-tools.ts +57 -19
  706. package/src/core/prompt-command-catalog.ts +46 -0
  707. package/src/core/prompt-command-runtime.ts +1816 -0
  708. package/src/core/prompt-command-state.ts +211 -0
  709. package/src/core/prompts.ts +173 -41
  710. package/src/core/reference-payload.ts +5 -63
  711. package/src/core/resources.ts +61 -5
  712. package/src/core/runtime-project-paths.ts +21 -1
  713. package/src/core/settings-menu.ts +12 -6
  714. package/src/core/source-analyzer.ts +27 -7
  715. package/src/core/token-counter.ts +6 -76
  716. package/src/core/tool-runner.ts +38 -317
  717. package/src/index.ts +2047 -947
  718. package/src/resources/instructions/git_commit.md +16 -0
  719. package/src/resources/instructions/git_read-only.md +2 -0
  720. package/src/resources/prompts/analyze.md +12 -13
  721. package/src/resources/prompts/change.md +21 -59
  722. package/src/resources/prompts/check.md +14 -16
  723. package/src/resources/prompts/cover.md +21 -59
  724. package/src/resources/prompts/create.md +5 -4
  725. package/src/resources/prompts/fix.md +20 -58
  726. package/src/resources/prompts/flowchart.md +14 -49
  727. package/src/resources/prompts/implement.md +14 -50
  728. package/src/resources/prompts/new.md +20 -58
  729. package/src/resources/prompts/readme.md +14 -50
  730. package/src/resources/prompts/recreate.md +14 -45
  731. package/src/resources/prompts/refactor.md +20 -58
  732. package/src/resources/prompts/references.md +7 -43
  733. package/src/resources/prompts/renumber.md +8 -39
  734. package/src/resources/prompts/workflow.md +14 -50
  735. package/src/resources/prompts/write.md +5 -4
  736. package/tests/attended-results-scenarios.ts +30 -136
  737. package/tests/cli-command-option-parity.test.ts +148 -192
  738. package/tests/debug-extension-harness.test.ts +77 -70
  739. package/tests/extension-registration.test.ts +3205 -658
  740. package/tests/fixtures_attended_results/project/compress-line-numbers.json +1 -1
  741. package/tests/fixtures_attended_results/project/compress.json +1 -1
  742. package/tests/fixtures_attended_results/project/find-line-numbers.json +1 -1
  743. package/tests/fixtures_attended_results/project/find.json +1 -1
  744. package/tests/fixtures_attended_results/project/references.json +2 -2
  745. package/tests/fixtures_attended_results/standalone/files-compress/fixture_go.go.json +1 -1
  746. package/tests/fixtures_attended_results/standalone/files-compress-line-numbers/fixture_go.go.json +1 -1
  747. package/tests/fixtures_attended_results/standalone/files-find/fixture_go.go.json +1 -1
  748. package/tests/fixtures_attended_results/standalone/files-find-line-numbers/fixture_go.go.json +1 -1
  749. package/tests/fixtures_attended_results/standalone/files-references/fixture_c.c.json +1 -1
  750. package/tests/fixtures_attended_results/standalone/files-references/fixture_cpp.cpp.json +1 -1
  751. package/tests/fixtures_attended_results/standalone/files-references/fixture_csharp.cs.json +1 -1
  752. package/tests/fixtures_attended_results/standalone/files-references/fixture_elixir.ex.json +1 -1
  753. package/tests/fixtures_attended_results/standalone/files-references/fixture_go.go.json +1 -1
  754. package/tests/fixtures_attended_results/standalone/files-references/fixture_haskell.hs.json +1 -1
  755. package/tests/fixtures_attended_results/standalone/files-references/fixture_java.java.json +1 -1
  756. package/tests/fixtures_attended_results/standalone/files-references/fixture_javascript.js.json +1 -1
  757. package/tests/fixtures_attended_results/standalone/files-references/fixture_kotlin.kt.json +1 -1
  758. package/tests/fixtures_attended_results/standalone/files-references/fixture_lua.lua.json +1 -1
  759. package/tests/fixtures_attended_results/standalone/files-references/fixture_perl.pl.json +1 -1
  760. package/tests/fixtures_attended_results/standalone/files-references/fixture_php.php.json +1 -1
  761. package/tests/fixtures_attended_results/standalone/files-references/fixture_python.py.json +1 -1
  762. package/tests/fixtures_attended_results/standalone/files-references/fixture_ruby.rb.json +1 -1
  763. package/tests/fixtures_attended_results/standalone/files-references/fixture_rust.rs.json +1 -1
  764. package/tests/fixtures_attended_results/standalone/files-references/fixture_scala.scala.json +1 -1
  765. package/tests/fixtures_attended_results/standalone/files-references/fixture_shell.sh.json +1 -1
  766. package/tests/fixtures_attended_results/standalone/files-references/fixture_swift.swift.json +1 -1
  767. package/tests/fixtures_attended_results/standalone/files-references/fixture_typescript.ts.json +1 -1
  768. package/tests/fixtures_attended_results/standalone/files-references/fixture_zig.zig.json +1 -1
  769. package/tests/helpers.ts +24 -15
  770. package/tests/oracle-project.test.ts +29 -30
  771. package/tests/oracle-standalone.test.ts +27 -1
  772. package/tests/prompt-rendering.test.ts +40 -9
  773. package/tests/python_oracle_stubs/tiktoken.py +76 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file
3
3
  * @brief Loads, normalizes, and persists pi-usereq project configuration.
4
- * @details Defines the configuration schema, default directory conventions, JSON serialization helpers, and prompt placeholder expansion paths. Runtime is dominated by filesystem reads and writes plus linear normalization over configured entries. Side effects include config-file persistence under `.pi-usereq`.
4
+ * @details Defines the configuration schema, default directory conventions, JSON serialization helpers, and prompt placeholder expansion paths. Runtime is dominated by filesystem reads and writes plus linear normalization over configured entries. Side effects include config-file persistence under `.pi-usereq.json`.
5
5
  */
6
6
 
7
7
  import fs from "node:fs";
@@ -12,6 +12,7 @@ import {
12
12
  buildRuntimePathFacts,
13
13
  formatRuntimePathForDisplay,
14
14
  getConfigPath,
15
+ normalizeRelativeDirContract,
15
16
  } from "./path-context.js";
16
17
  import {
17
18
  DEFAULT_PI_NOTIFY_CMD,
@@ -21,6 +22,7 @@ import {
21
22
  DEFAULT_PI_NOTIFY_SOUND_LOW_CMD,
22
23
  DEFAULT_PI_NOTIFY_SOUND_MID_CMD,
23
24
  DEFAULT_PI_NOTIFY_SOUND_TOGGLE_SHORTCUT,
25
+ hasPiNotifyPushoverCredentials,
24
26
  normalizePiNotifyCommand,
25
27
  normalizePiNotifyPushoverCredential,
26
28
  normalizePiNotifyPushoverPriority,
@@ -28,6 +30,20 @@ import {
28
30
  normalizePiNotifySoundLevel,
29
31
  normalizePiNotifyTemplateValue,
30
32
  } from "./pi-notify.js";
33
+ import {
34
+ DEFAULT_DEBUG_ENABLED,
35
+ DEFAULT_DEBUG_LOG_FILE,
36
+ DEFAULT_DEBUG_LOG_ON_STATUS,
37
+ DEFAULT_DEBUG_STATUS_CHANGES,
38
+ DEFAULT_DEBUG_WORKFLOW_EVENTS,
39
+ normalizeDebugEnabled,
40
+ normalizeDebugEnabledPrompts,
41
+ normalizeDebugEnabledTools,
42
+ normalizeDebugLogFile,
43
+ normalizeDebugLogOnStatus,
44
+ normalizeDebugStatusChanges,
45
+ normalizeDebugWorkflowEvents,
46
+ } from "./debug-runtime.js";
31
47
  import { normalizeEnabledPiUsereqTools } from "./pi-usereq-tools.js";
32
48
  import { makeRelativeIfContainsProject } from "./utils.js";
33
49
 
@@ -41,16 +57,41 @@ export interface StaticCheckEntry {
41
57
  params?: string[];
42
58
  }
43
59
 
60
+ /**
61
+ * @brief Represents the persisted per-language static-check enable flag.
62
+ * @details Narrows persisted per-language enablement to the documented `enable|disable` domain reused by configuration loading, menu toggles, and static-check dispatch. The alias is compile-time only and introduces no runtime cost.
63
+ */
64
+ export type StaticCheckEnabled = "enable" | "disable";
65
+
66
+ /**
67
+ * @brief Describes one persisted per-language static-check configuration object.
68
+ * @details Couples the per-language enable flag with the ordered checker-entry list so menu toggles, config serialization, and execution dispatch can distinguish configured-but-disabled languages from enabled active checker lists. The interface is compile-time only and introduces no runtime cost.
69
+ */
70
+ export interface StaticCheckLanguageConfig {
71
+ enabled: StaticCheckEnabled;
72
+ checkers: StaticCheckEntry[];
73
+ }
74
+
44
75
  /**
45
76
  * @brief Defines the persisted pi-usereq project configuration schema.
46
- * @details Captures documentation paths, source/test directory selection, static-check configuration, enabled startup tools, and notification settings while excluding runtime-derived path metadata. The interface is compile-time only and introduces no runtime side effects.
77
+ * @details Captures documentation paths, source/test directory selection, per-language static-check enablement and checker configuration, prompt-command worktree settings, enabled startup tools, and notification settings while excluding runtime-derived path metadata. The interface is compile-time only and introduces no runtime side effects.
47
78
  */
48
79
  export interface UseReqConfig {
49
80
  "docs-dir": string;
50
81
  "tests-dir": string;
51
82
  "src-dir": string[];
52
- "static-check": Record<string, StaticCheckEntry[]>;
83
+ "static-check": Record<string, StaticCheckLanguageConfig>;
53
84
  "enabled-tools": string[];
85
+ AUTO_GIT_COMMIT: "enable" | "disable";
86
+ GIT_WORKTREE_ENABLED: "enable" | "disable";
87
+ GIT_WORKTREE_PREFIX: string;
88
+ DEBUG_ENABLED: "enable" | "disable";
89
+ DEBUG_LOG_FILE: string;
90
+ DEBUG_STATUS_CHANGES: "enable" | "disable";
91
+ DEBUG_WORKFLOW_EVENTS: "enable" | "disable";
92
+ DEBUG_LOG_ON_STATUS: "any" | "idle" | "checking" | "running" | "merging" | "error";
93
+ DEBUG_ENABLED_TOOLS: string[];
94
+ DEBUG_ENABLED_PROMPTS: string[];
54
95
  "notify-enabled": boolean;
55
96
  "notify-on-completed": boolean;
56
97
  "notify-on-interrupted": boolean;
@@ -91,9 +132,250 @@ export const DEFAULT_TESTS_DIR = "tests";
91
132
  * @details The array seeds newly created configs and repairs invalid persisted source selections. Access complexity is O(1).
92
133
  */
93
134
  export const DEFAULT_SRC_DIRS = ["src"];
135
+ /**
136
+ * @brief Defines the canonical supported static-check language order used by default config serialization.
137
+ * @details The array lists every supported user-configurable language exactly once so default config builders and config serializers can emit deterministic per-language records. Access complexity is O(1).
138
+ */
139
+ export const DEFAULT_STATIC_CHECK_LANGUAGES = [
140
+ "C",
141
+ "C#",
142
+ "C++",
143
+ "Elixir",
144
+ "Go",
145
+ "Haskell",
146
+ "Java",
147
+ "JavaScript",
148
+ "Kotlin",
149
+ "Lua",
150
+ "Perl",
151
+ "PHP",
152
+ "Python",
153
+ "Ruby",
154
+ "Rust",
155
+ "Scala",
156
+ "Shell",
157
+ "Swift",
158
+ "TypeScript",
159
+ "Zig",
160
+ ] as const;
161
+
162
+ /**
163
+ * @brief Defines the default static-check entries per language.
164
+ * @details Seeds the documented default Command checker lists for enabled-by-default languages while languages omitted from the map default to empty checker lists. Access complexity is O(1).
165
+ * @satisfies REQ-250, REQ-251, REQ-252
166
+ */
167
+ const DEFAULT_STATIC_CHECK_CHECKERS: Record<string, StaticCheckEntry[]> = {
168
+ C: [
169
+ {
170
+ module: "Command",
171
+ cmd: "cppcheck",
172
+ params: [
173
+ "--error-exitcode=1",
174
+ "--enable=warning,style,performance,portability",
175
+ "--std=c11",
176
+ ],
177
+ },
178
+ {
179
+ module: "Command",
180
+ cmd: "clang-format",
181
+ params: ["--dry-run", "--Werror"],
182
+ },
183
+ ],
184
+ "C++": [
185
+ {
186
+ module: "Command",
187
+ cmd: "cppcheck",
188
+ params: [
189
+ "--error-exitcode=1",
190
+ "--enable=warning,style,performance,portability",
191
+ "--std=c++20",
192
+ ],
193
+ },
194
+ {
195
+ module: "Command",
196
+ cmd: "clang-format",
197
+ params: ["--dry-run", "--Werror"],
198
+ },
199
+ ],
200
+ Python: [
201
+ {
202
+ module: "Command",
203
+ cmd: "pyright",
204
+ params: ["--outputjson"],
205
+ },
206
+ {
207
+ module: "Command",
208
+ cmd: "ruff",
209
+ params: ["check"],
210
+ },
211
+ ],
212
+ JavaScript: [
213
+ {
214
+ module: "Command",
215
+ cmd: "node",
216
+ params: ["--check"],
217
+ },
218
+ ],
219
+ TypeScript: [
220
+ {
221
+ module: "Command",
222
+ cmd: "npx",
223
+ params: ["eslint"],
224
+ },
225
+ ],
226
+ };
227
+
228
+ /**
229
+ * @brief Clones one static-check entry into its persisted shape.
230
+ * @details Copies only the stable module, cmd, and params fields so runtime-only or unknown metadata never leaks into persisted configuration payloads. Runtime is O(p) in parameter count. No external state is mutated.
231
+ * @param[in] entry {StaticCheckEntry} Source static-check entry.
232
+ * @return {StaticCheckEntry} Persistable static-check entry clone.
233
+ */
234
+ function cloneStaticCheckEntry(entry: StaticCheckEntry): StaticCheckEntry {
235
+ const params = Array.isArray(entry.params)
236
+ ? entry.params.map((value) => String(value)).filter((value) => value.trim().length > 0)
237
+ : [];
238
+ return {
239
+ module: String(entry.module ?? ""),
240
+ ...(typeof entry.cmd === "string" && entry.cmd.trim() ? { cmd: entry.cmd.trim() } : {}),
241
+ ...(params.length > 0 ? { params } : {}),
242
+ };
243
+ }
244
+
245
+ /**
246
+ * @brief Builds one per-language static-check configuration object.
247
+ * @details Clones the supplied checker entries, derives `enabled` from the explicit argument or checker-list emptiness, and preserves checker order for menu and dispatch determinism. Runtime is O(c + p). No external state is mutated.
248
+ * @param[in] checkers {StaticCheckEntry[]} Ordered checker entries.
249
+ * @param[in] enabled {StaticCheckEnabled | undefined} Optional explicit enable flag.
250
+ * @return {StaticCheckLanguageConfig} Normalized per-language config object.
251
+ */
252
+ export function createStaticCheckLanguageConfig(
253
+ checkers: StaticCheckEntry[],
254
+ enabled?: StaticCheckEnabled,
255
+ ): StaticCheckLanguageConfig {
256
+ const normalizedCheckers = checkers.map(cloneStaticCheckEntry);
257
+ return {
258
+ enabled: enabled ?? (normalizedCheckers.length > 0 ? "enable" : "disable"),
259
+ checkers: normalizedCheckers,
260
+ };
261
+ }
262
+
263
+ /**
264
+ * @brief Returns the documented default static-check configuration.
265
+ * @details Emits one per-language config object for every supported language, enabling only languages with documented default checker entries and leaving all remaining languages disabled with empty checker lists. Runtime is O(l + c). No external state is mutated.
266
+ * @return {Record<string, StaticCheckLanguageConfig>} Fresh default static-check config.
267
+ * @satisfies REQ-249, REQ-250, REQ-251, REQ-252
268
+ */
269
+ export function getDefaultStaticCheckConfig(): Record<string, StaticCheckLanguageConfig> {
270
+ return Object.fromEntries(DEFAULT_STATIC_CHECK_LANGUAGES.map((language) => [
271
+ language,
272
+ createStaticCheckLanguageConfig(DEFAULT_STATIC_CHECK_CHECKERS[language] ?? []),
273
+ ]));
274
+ }
275
+
276
+ /**
277
+ * @brief Normalizes one persisted per-language static-check enable flag.
278
+ * @details Accepts only the documented `enable|disable` values and falls back to the supplied default when the candidate is absent or invalid. Runtime is O(1). No external state is mutated.
279
+ * @param[in] value {unknown} Candidate persisted enable flag.
280
+ * @param[in] defaultValue {StaticCheckEnabled} Fallback enable flag.
281
+ * @return {StaticCheckEnabled} Canonical per-language enable flag.
282
+ * @satisfies REQ-249
283
+ */
284
+ export function normalizeStaticCheckEnabled(
285
+ value: unknown,
286
+ defaultValue: StaticCheckEnabled,
287
+ ): StaticCheckEnabled {
288
+ return value === "enable" || value === "disable" ? value : defaultValue;
289
+ }
290
+
291
+ /**
292
+ * @brief Resolves the active checker list for one language.
293
+ * @details Returns the persisted checker list only when the language is enabled; disabled or missing languages yield an empty list without mutating the source config. Runtime is O(c). No external state is mutated.
294
+ * @param[in] staticCheckConfig {Record<string, StaticCheckLanguageConfig>} Effective static-check config.
295
+ * @param[in] language {string} Canonical language name.
296
+ * @return {StaticCheckEntry[]} Active checker list for the language.
297
+ * @satisfies REQ-019
298
+ */
299
+ export function getActiveStaticCheckEntries(
300
+ staticCheckConfig: Record<string, StaticCheckLanguageConfig>,
301
+ language: string,
302
+ ): StaticCheckEntry[] {
303
+ const languageConfig = staticCheckConfig[language];
304
+ if (!languageConfig || languageConfig.enabled !== "enable") {
305
+ return [];
306
+ }
307
+ return languageConfig.checkers.map(cloneStaticCheckEntry);
308
+ }
309
+
310
+ /**
311
+ * @brief Defines the default automatic git-commit prompt mode.
312
+ * @details New project configs enable bundled commit-instruction injection unless the persisted project config explicitly disables it. Access complexity is O(1).
313
+ * @satisfies CTN-001, REQ-212
314
+ */
315
+ export const DEFAULT_AUTO_GIT_COMMIT = "enable" as const;
316
+ /**
317
+ * @brief Normalizes one persisted automatic git-commit mode value.
318
+ * @details Accepts only the documented `enable|disable` values and falls back to `DEFAULT_AUTO_GIT_COMMIT` for all other payloads. Runtime is O(1). No side effects occur.
319
+ * @param[in] value {unknown} Candidate persisted automatic git-commit payload.
320
+ * @return {"enable" | "disable"} Canonical automatic git-commit mode.
321
+ * @satisfies REQ-212
322
+ */
323
+ export function normalizeAutoGitCommit(value: unknown): "enable" | "disable" {
324
+ return value === "disable" ? "disable" : DEFAULT_AUTO_GIT_COMMIT;
325
+ }
326
+ /**
327
+ * @brief Defines the default worktree orchestration mode.
328
+ * @details New project configs enable prompt-command worktree orchestration unless the persisted project config explicitly disables it. Access complexity is O(1).
329
+ * @satisfies CTN-001, REQ-204
330
+ */
331
+ export const DEFAULT_GIT_WORKTREE_ENABLED = "enable" as const;
332
+ /**
333
+ * @brief Normalizes one persisted worktree-enable flag value.
334
+ * @details Accepts only the documented `enable|disable` values and falls back to `DEFAULT_GIT_WORKTREE_ENABLED` for all other payloads. Runtime is O(1). No side effects occur.
335
+ * @param[in] value {unknown} Candidate persisted worktree-enable payload.
336
+ * @return {"enable" | "disable"} Canonical persisted worktree-enable mode.
337
+ * @satisfies REQ-204
338
+ */
339
+ export function normalizeGitWorktreeEnabled(value: unknown): "enable" | "disable" {
340
+ return value === "disable" ? "disable" : DEFAULT_GIT_WORKTREE_ENABLED;
341
+ }
342
+ /**
343
+ * @brief Resolves the effective worktree mode after automatic-commit policy is applied.
344
+ * @details Forces `disable` whenever `AUTO_GIT_COMMIT` is disabled; otherwise preserves the normalized persisted worktree flag. Runtime is O(1). No side effects occur.
345
+ * @param[in] autoGitCommit {"enable" | "disable"} Effective automatic git-commit mode.
346
+ * @param[in] gitWorktreeEnabled {"enable" | "disable"} Normalized persisted worktree-enable mode.
347
+ * @return {"enable" | "disable"} Effective worktree mode used by menus, persistence, and prompt execution.
348
+ * @satisfies REQ-204, REQ-215
349
+ */
350
+ export function resolveEffectiveGitWorktreeEnabled(
351
+ autoGitCommit: "enable" | "disable",
352
+ gitWorktreeEnabled: "enable" | "disable",
353
+ ): "enable" | "disable" {
354
+ return autoGitCommit === "disable" ? "disable" : gitWorktreeEnabled;
355
+ }
356
+ /**
357
+ * @brief Defines the default static prefix used by generated prompt-command worktree names.
358
+ * @details The prefix is concatenated verbatim ahead of the repository basename inside slash-command-owned worktree-name generation. Access complexity is O(1).
359
+ * @satisfies CTN-001, REQ-205
360
+ */
361
+ export const DEFAULT_GIT_WORKTREE_PREFIX = "PI-useReq-";
362
+ /**
363
+ * @brief Normalizes one persisted worktree-name prefix value.
364
+ * @details Accepts only non-empty strings, trims surrounding whitespace, and falls back to `DEFAULT_GIT_WORKTREE_PREFIX` when the candidate is absent or blank. Runtime is O(n) in prefix length. No side effects occur.
365
+ * @param[in] value {unknown} Candidate persisted prefix payload.
366
+ * @return {string} Canonical worktree-name prefix.
367
+ * @satisfies REQ-205
368
+ */
369
+ export function normalizeGitWorktreePrefix(value: unknown): string {
370
+ if (typeof value !== "string") {
371
+ return DEFAULT_GIT_WORKTREE_PREFIX;
372
+ }
373
+ const trimmedValue = value.trim();
374
+ return trimmedValue === "" ? DEFAULT_GIT_WORKTREE_PREFIX : trimmedValue;
375
+ }
94
376
  /**
95
377
  * @brief Computes the per-project config file path.
96
- * @details Joins the project base with `.pi-usereq/config.json`, producing the canonical persistence location used by CLI and extension code. Time complexity is O(1). No I/O side effects occur.
378
+ * @details Joins the project base with `.pi-usereq.json`, producing the canonical persistence location used by CLI and extension code. Time complexity is O(1). No I/O side effects occur.
97
379
  * @param[in] projectBase {string} Absolute project root path.
98
380
  * @return {string} Absolute config file path.
99
381
  */
@@ -103,18 +385,28 @@ export function getProjectConfigPath(projectBase: string): string {
103
385
 
104
386
  /**
105
387
  * @brief Builds the default project configuration.
106
- * @details Populates canonical docs/test/source directories, the default startup tool set, default command-notify, sound, and Pushover fields, and excludes runtime-derived path metadata. Time complexity is O(n) in default tool count. No filesystem side effects occur.
388
+ * @details Populates canonical docs/test/source directories, documented per-language static-check defaults, default prompt-command worktree settings, default debug fields including dedicated workflow-event logging, the default startup tool set, default command-notify, sound, and Pushover fields, and excludes runtime-derived path metadata. Time complexity is O(n) in default selector count plus default static-check entry count. No filesystem side effects occur.
107
389
  * @param[in] projectBase {string} Absolute project root path.
108
390
  * @return {UseReqConfig} Fresh default configuration object.
109
- * @satisfies CTN-001, CTN-012, REQ-066, REQ-146, REQ-163, REQ-174, REQ-178, REQ-184, REQ-185, REQ-196
391
+ * @satisfies CTN-001, CTN-012, CTN-013, REQ-066, REQ-146, REQ-163, REQ-174, REQ-178, REQ-184, REQ-185, REQ-196, REQ-204, REQ-205, REQ-212, REQ-236, REQ-237, REQ-238, REQ-239, REQ-249, REQ-250, REQ-251, REQ-252, REQ-277
110
392
  */
111
393
  export function getDefaultConfig(_projectBase: string): UseReqConfig {
112
394
  return {
113
395
  "docs-dir": DEFAULT_DOCS_DIR,
114
396
  "tests-dir": DEFAULT_TESTS_DIR,
115
397
  "src-dir": [...DEFAULT_SRC_DIRS],
116
- "static-check": {},
398
+ "static-check": getDefaultStaticCheckConfig(),
117
399
  "enabled-tools": normalizeEnabledPiUsereqTools(undefined),
400
+ AUTO_GIT_COMMIT: DEFAULT_AUTO_GIT_COMMIT,
401
+ GIT_WORKTREE_ENABLED: DEFAULT_GIT_WORKTREE_ENABLED,
402
+ GIT_WORKTREE_PREFIX: DEFAULT_GIT_WORKTREE_PREFIX,
403
+ DEBUG_ENABLED: DEFAULT_DEBUG_ENABLED,
404
+ DEBUG_LOG_FILE: DEFAULT_DEBUG_LOG_FILE,
405
+ DEBUG_STATUS_CHANGES: DEFAULT_DEBUG_STATUS_CHANGES,
406
+ DEBUG_WORKFLOW_EVENTS: DEFAULT_DEBUG_WORKFLOW_EVENTS,
407
+ DEBUG_LOG_ON_STATUS: DEFAULT_DEBUG_LOG_ON_STATUS,
408
+ DEBUG_ENABLED_TOOLS: [],
409
+ DEBUG_ENABLED_PROMPTS: [],
118
410
  "notify-enabled": false,
119
411
  "notify-on-completed": true,
120
412
  "notify-on-interrupted": false,
@@ -140,13 +432,69 @@ export function getDefaultConfig(_projectBase: string): UseReqConfig {
140
432
  };
141
433
  }
142
434
 
435
+ /**
436
+ * @brief Normalizes one raw checker-entry array from persisted config.
437
+ * @details Accepts only object entries with a non-empty module string, trims optional command text, filters blank params, and drops malformed records without applying any legacy schema migrations. Runtime is O(c + p). No external state is mutated.
438
+ * @param[in] value {unknown} Candidate persisted checker array.
439
+ * @return {StaticCheckEntry[]} Normalized checker-entry vector.
440
+ */
441
+ function normalizeStaticCheckEntries(value: unknown): StaticCheckEntry[] {
442
+ if (!Array.isArray(value)) {
443
+ return [];
444
+ }
445
+ const entries: StaticCheckEntry[] = [];
446
+ for (const item of value) {
447
+ if (!item || typeof item !== "object") {
448
+ continue;
449
+ }
450
+ const entry = item as Record<string, unknown>;
451
+ if (typeof entry.module !== "string" || entry.module.trim() === "") {
452
+ continue;
453
+ }
454
+ entries.push(cloneStaticCheckEntry({
455
+ module: entry.module,
456
+ ...(typeof entry.cmd === "string" ? { cmd: entry.cmd } : {}),
457
+ ...(Array.isArray(entry.params) ? { params: entry.params.map(String) } : {}),
458
+ }));
459
+ }
460
+ return entries;
461
+ }
462
+
463
+ /**
464
+ * @brief Normalizes the persisted per-language static-check configuration map.
465
+ * @details Accepts only object-valued language entries using the new `{ enabled, checkers }` schema, normalizes missing or invalid `enabled` values from checker-list presence, and drops malformed or legacy non-object language payloads without migration. Runtime is O(l + c + p). No external state is mutated.
466
+ * @param[in] value {unknown} Candidate persisted static-check payload.
467
+ * @return {Record<string, StaticCheckLanguageConfig>} Normalized per-language static-check map.
468
+ * @satisfies REQ-249
469
+ */
470
+ function normalizeStaticCheckConfig(
471
+ value: unknown,
472
+ ): Record<string, StaticCheckLanguageConfig> {
473
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
474
+ return {};
475
+ }
476
+ const config: Record<string, StaticCheckLanguageConfig> = {};
477
+ for (const [language, languageValue] of Object.entries(value as Record<string, unknown>)) {
478
+ if (!languageValue || typeof languageValue !== "object" || Array.isArray(languageValue)) {
479
+ continue;
480
+ }
481
+ const languageRecord = languageValue as Record<string, unknown>;
482
+ const checkers = normalizeStaticCheckEntries(languageRecord.checkers);
483
+ config[language] = createStaticCheckLanguageConfig(
484
+ checkers,
485
+ normalizeStaticCheckEnabled(languageRecord.enabled, checkers.length > 0 ? "enable" : "disable"),
486
+ );
487
+ }
488
+ return config;
489
+ }
490
+
143
491
  /**
144
492
  * @brief Loads and sanitizes the persisted project configuration.
145
- * @details Returns defaults when the config file does not exist. Otherwise parses JSON, validates directory and static-check field shapes, normalizes enabled tool names plus notify, sound, and Pushover fields, applies documented per-flag defaults for missing payloads, and ignores removed or runtime-derived path metadata. Runtime is O(n) in config size. Side effects are limited to filesystem reads.
493
+ * @details Returns defaults when the config file does not exist. Otherwise parses JSON, validates directory and per-language static-check object shapes, normalizes enabled tool names plus prompt-command worktree, debug, notify, sound, and Pushover fields including dedicated workflow-event logging, preserves non-empty template text verbatim, forces the effective worktree mode off when automatic git commit is disabled, forces effective Pushover disablement until both credentials are populated, applies documented per-flag defaults for missing payloads, and ignores removed, malformed, or runtime-derived path metadata without legacy schema migration. Runtime is O(n) in config size. Side effects are limited to filesystem reads.
146
494
  * @param[in] projectBase {string} Absolute project root path.
147
495
  * @return {UseReqConfig} Sanitized effective configuration.
148
496
  * @throws {ReqError} Throws with exit code `11` when the config file contains invalid JSON or a non-object payload.
149
- * @satisfies CTN-012, REQ-066, REQ-146, REQ-163, REQ-174, REQ-178, REQ-184, REQ-185, REQ-196
497
+ * @satisfies CTN-012, CTN-013, REQ-066, REQ-146, REQ-163, REQ-174, REQ-178, REQ-184, REQ-185, REQ-196, REQ-204, REQ-205, REQ-212, REQ-215, REQ-234, REQ-235, REQ-236, REQ-237, REQ-238, REQ-239, REQ-249, REQ-277
150
498
  */
151
499
  export function loadConfig(projectBase: string): UseReqConfig {
152
500
  const configPath = getProjectConfigPath(projectBase);
@@ -165,15 +513,36 @@ export function loadConfig(projectBase: string): UseReqConfig {
165
513
  throw new ReqError(`Error: invalid ${configPath}`, 11);
166
514
  }
167
515
  const data = payload as Record<string, unknown>;
168
- const docsDir = typeof data["docs-dir"] === "string" && data["docs-dir"].trim() ? data["docs-dir"] : DEFAULT_DOCS_DIR;
169
- const testsDir = typeof data["tests-dir"] === "string" && data["tests-dir"].trim() ? data["tests-dir"] : DEFAULT_TESTS_DIR;
170
- const srcDir = Array.isArray(data["src-dir"]) && data["src-dir"].every((item) => typeof item === "string" && item.trim())
171
- ? (data["src-dir"] as string[])
172
- : [...DEFAULT_SRC_DIRS];
173
- const staticCheck = typeof data["static-check"] === "object" && data["static-check"] !== null
174
- ? (data["static-check"] as Record<string, StaticCheckEntry[]>)
175
- : {};
516
+ const docsDirCandidate = typeof data["docs-dir"] === "string"
517
+ ? normalizeRelativeDirContract(data["docs-dir"])
518
+ : "";
519
+ const testsDirCandidate = typeof data["tests-dir"] === "string"
520
+ ? normalizeRelativeDirContract(data["tests-dir"])
521
+ : "";
522
+ const srcDirCandidate = Array.isArray(data["src-dir"])
523
+ ? data["src-dir"]
524
+ .filter((item): item is string => typeof item === "string")
525
+ .map((item) => normalizeRelativeDirContract(item))
526
+ .filter((item) => item !== "")
527
+ : [];
528
+ const docsDir = docsDirCandidate || DEFAULT_DOCS_DIR;
529
+ const testsDir = testsDirCandidate || DEFAULT_TESTS_DIR;
530
+ const srcDir = srcDirCandidate.length > 0 ? srcDirCandidate : [...DEFAULT_SRC_DIRS];
531
+ const staticCheck = normalizeStaticCheckConfig(data["static-check"]);
176
532
  const enabledTools = normalizeEnabledPiUsereqTools(data["enabled-tools"]);
533
+ const autoGitCommit = normalizeAutoGitCommit(data.AUTO_GIT_COMMIT);
534
+ const gitWorktreeEnabled = resolveEffectiveGitWorktreeEnabled(
535
+ autoGitCommit,
536
+ normalizeGitWorktreeEnabled(data.GIT_WORKTREE_ENABLED),
537
+ );
538
+ const gitWorktreePrefix = normalizeGitWorktreePrefix(data.GIT_WORKTREE_PREFIX);
539
+ const debugEnabled = normalizeDebugEnabled(data.DEBUG_ENABLED);
540
+ const debugLogFile = normalizeDebugLogFile(data.DEBUG_LOG_FILE);
541
+ const debugStatusChanges = normalizeDebugStatusChanges(data.DEBUG_STATUS_CHANGES);
542
+ const debugWorkflowEvents = normalizeDebugWorkflowEvents(data.DEBUG_WORKFLOW_EVENTS);
543
+ const debugLogOnStatus = normalizeDebugLogOnStatus(data.DEBUG_LOG_ON_STATUS);
544
+ const debugEnabledTools = normalizeDebugEnabledTools(data.DEBUG_ENABLED_TOOLS);
545
+ const debugEnabledPrompts = normalizeDebugEnabledPrompts(data.DEBUG_ENABLED_PROMPTS);
177
546
  const notifyEnabled = data["notify-enabled"] === true;
178
547
  const notifyOnCompleted = data["notify-on-completed"] !== false;
179
548
  const notifyOnInterrupted = data["notify-on-interrupted"] === true;
@@ -183,12 +552,16 @@ export function loadConfig(projectBase: string): UseReqConfig {
183
552
  const notifySoundOnInterrupted = data["notify-sound-on-interrupted"] === true;
184
553
  const notifySoundOnFailed = data["notify-sound-on-failed"] === true;
185
554
  const notifySoundToggleShortcut = normalizePiNotifyShortcut(data["notify-sound-toggle-shortcut"]);
186
- const pushoverEnabled = data["notify-pushover-enabled"] === true;
187
555
  const pushoverOnCompleted = data["notify-pushover-on-completed"] !== false;
188
556
  const pushoverOnInterrupted = data["notify-pushover-on-interrupted"] === true;
189
557
  const pushoverOnFailed = data["notify-pushover-on-failed"] === true;
190
558
  const pushoverUserKey = normalizePiNotifyPushoverCredential(data["notify-pushover-user-key"]);
191
559
  const pushoverApiToken = normalizePiNotifyPushoverCredential(data["notify-pushover-api-token"]);
560
+ const pushoverEnabled = data["notify-pushover-enabled"] === true
561
+ && hasPiNotifyPushoverCredentials({
562
+ "notify-pushover-user-key": pushoverUserKey,
563
+ "notify-pushover-api-token": pushoverApiToken,
564
+ });
192
565
  const pushoverPriority = normalizePiNotifyPushoverPriority(data["notify-pushover-priority"]);
193
566
  const pushoverTitle = normalizePiNotifyTemplateValue(
194
567
  data["notify-pushover-title"],
@@ -209,6 +582,16 @@ export function loadConfig(projectBase: string): UseReqConfig {
209
582
  "src-dir": srcDir,
210
583
  "static-check": staticCheck,
211
584
  "enabled-tools": enabledTools,
585
+ AUTO_GIT_COMMIT: autoGitCommit,
586
+ GIT_WORKTREE_ENABLED: gitWorktreeEnabled,
587
+ GIT_WORKTREE_PREFIX: gitWorktreePrefix,
588
+ DEBUG_ENABLED: debugEnabled,
589
+ DEBUG_LOG_FILE: debugLogFile,
590
+ DEBUG_STATUS_CHANGES: debugStatusChanges,
591
+ DEBUG_WORKFLOW_EVENTS: debugWorkflowEvents,
592
+ DEBUG_LOG_ON_STATUS: debugLogOnStatus,
593
+ DEBUG_ENABLED_TOOLS: debugEnabledTools,
594
+ DEBUG_ENABLED_PROMPTS: debugEnabledPrompts,
212
595
  "notify-enabled": notifyEnabled,
213
596
  "notify-on-completed": notifyOnCompleted,
214
597
  "notify-on-interrupted": notifyOnInterrupted,
@@ -236,27 +619,47 @@ export function loadConfig(projectBase: string): UseReqConfig {
236
619
 
237
620
  /**
238
621
  * @brief Builds the persisted configuration payload that excludes runtime-derived fields.
239
- * @details Copies only the canonical persisted configuration keys into a fresh object so runtime-derived metadata such as `base-path` and `git-path` can never be written to disk while preserving notification and Pushover settings verbatim. Runtime is O(n) in config size. No external state is mutated.
622
+ * @details Copies only the canonical persisted configuration keys into a fresh object so runtime-derived metadata such as `base-path` and `git-path` can never be written to disk, serializes per-language static-check objects with key order `enabled` then `checkers`, normalizes `GIT_WORKTREE_PREFIX` plus debug fields including dedicated workflow-event logging, forces persisted worktree disablement when automatic git commit is disabled, forces persisted Pushover disablement until both credentials are populated, and preserves the remaining notification and Pushover settings. Runtime is O(n) in config size. No external state is mutated.
240
623
  * @param[in] config {UseReqConfig} Effective configuration object.
241
624
  * @return {UseReqConfig} Persistable configuration payload.
242
- * @satisfies CTN-012, REQ-146, REQ-163
625
+ * @satisfies CTN-012, CTN-013, REQ-146, REQ-163, REQ-204, REQ-205, REQ-212, REQ-215, REQ-234, REQ-236, REQ-237, REQ-238, REQ-239, REQ-249, REQ-277
243
626
  */
244
627
  function buildPersistedConfig(config: UseReqConfig): UseReqConfig {
245
628
  return {
246
- "docs-dir": config["docs-dir"],
247
- "tests-dir": config["tests-dir"],
248
- "src-dir": [...config["src-dir"]],
629
+ "docs-dir": normalizeRelativeDirContract(config["docs-dir"]) || DEFAULT_DOCS_DIR,
630
+ "tests-dir": normalizeRelativeDirContract(config["tests-dir"]) || DEFAULT_TESTS_DIR,
631
+ "src-dir": (() => {
632
+ const normalizedSrcDir = config["src-dir"]
633
+ .map((entry) => normalizeRelativeDirContract(entry))
634
+ .filter((entry) => entry !== "");
635
+ return normalizedSrcDir.length > 0 ? normalizedSrcDir : [...DEFAULT_SRC_DIRS];
636
+ })(),
249
637
  "static-check": Object.fromEntries(
250
- Object.entries(config["static-check"]).map(([language, entries]) => [
638
+ Object.entries(config["static-check"]).map(([language, languageConfig]) => [
251
639
  language,
252
- entries.map((entry) => ({
253
- module: entry.module,
254
- ...(entry.cmd ? { cmd: entry.cmd } : {}),
255
- ...(entry.params ? { params: [...entry.params] } : {}),
256
- })),
640
+ {
641
+ enabled: normalizeStaticCheckEnabled(
642
+ languageConfig.enabled,
643
+ languageConfig.checkers.length > 0 ? "enable" : "disable",
644
+ ),
645
+ checkers: languageConfig.checkers.map(cloneStaticCheckEntry),
646
+ },
257
647
  ]),
258
648
  ),
259
649
  "enabled-tools": [...config["enabled-tools"]],
650
+ AUTO_GIT_COMMIT: normalizeAutoGitCommit(config.AUTO_GIT_COMMIT),
651
+ GIT_WORKTREE_ENABLED: resolveEffectiveGitWorktreeEnabled(
652
+ normalizeAutoGitCommit(config.AUTO_GIT_COMMIT),
653
+ config.GIT_WORKTREE_ENABLED,
654
+ ),
655
+ GIT_WORKTREE_PREFIX: normalizeGitWorktreePrefix(config.GIT_WORKTREE_PREFIX),
656
+ DEBUG_ENABLED: normalizeDebugEnabled(config.DEBUG_ENABLED),
657
+ DEBUG_LOG_FILE: normalizeDebugLogFile(config.DEBUG_LOG_FILE),
658
+ DEBUG_STATUS_CHANGES: normalizeDebugStatusChanges(config.DEBUG_STATUS_CHANGES),
659
+ DEBUG_WORKFLOW_EVENTS: normalizeDebugWorkflowEvents(config.DEBUG_WORKFLOW_EVENTS),
660
+ DEBUG_LOG_ON_STATUS: normalizeDebugLogOnStatus(config.DEBUG_LOG_ON_STATUS),
661
+ DEBUG_ENABLED_TOOLS: normalizeDebugEnabledTools(config.DEBUG_ENABLED_TOOLS),
662
+ DEBUG_ENABLED_PROMPTS: normalizeDebugEnabledPrompts(config.DEBUG_ENABLED_PROMPTS),
260
663
  "notify-enabled": config["notify-enabled"],
261
664
  "notify-on-completed": config["notify-on-completed"],
262
665
  "notify-on-interrupted": config["notify-on-interrupted"],
@@ -266,7 +669,8 @@ function buildPersistedConfig(config: UseReqConfig): UseReqConfig {
266
669
  "notify-sound-on-interrupted": config["notify-sound-on-interrupted"],
267
670
  "notify-sound-on-failed": config["notify-sound-on-failed"],
268
671
  "notify-sound-toggle-shortcut": config["notify-sound-toggle-shortcut"],
269
- "notify-pushover-enabled": config["notify-pushover-enabled"],
672
+ "notify-pushover-enabled": config["notify-pushover-enabled"]
673
+ && hasPiNotifyPushoverCredentials(config),
270
674
  "notify-pushover-on-completed": config["notify-pushover-on-completed"],
271
675
  "notify-pushover-on-interrupted": config["notify-pushover-on-interrupted"],
272
676
  "notify-pushover-on-failed": config["notify-pushover-on-failed"],
@@ -284,7 +688,7 @@ function buildPersistedConfig(config: UseReqConfig): UseReqConfig {
284
688
 
285
689
  /**
286
690
  * @brief Persists the project configuration to disk.
287
- * @details Creates the parent `.pi-usereq` directory when necessary, strips runtime-derived fields from the serialized payload, and writes formatted JSON terminated by a newline. Runtime is O(n) in serialized config size. Side effects include directory creation and file overwrite.
691
+ * @details Creates the base directory path when necessary, strips runtime-derived fields from the serialized payload, and writes formatted JSON terminated by a newline to `.pi-usereq.json`. Runtime is O(n) in serialized config size. Side effects include directory creation and file overwrite.
288
692
  * @param[in] projectBase {string} Absolute project root path.
289
693
  * @param[in] config {UseReqConfig} Configuration object to persist.
290
694
  * @return {void} No return value.
@@ -304,9 +708,17 @@ export function saveConfig(projectBase: string, config: UseReqConfig): void {
304
708
  * @return {UseReqConfig} Normalized configuration copy.
305
709
  */
306
710
  export function normalizeConfigPaths(projectBase: string, config: UseReqConfig): UseReqConfig {
307
- const docsDir = makeRelativeIfContainsProject(config["docs-dir"], projectBase).replace(/[/\\]+$/, "") || DEFAULT_DOCS_DIR;
308
- const testsDir = makeRelativeIfContainsProject(config["tests-dir"], projectBase).replace(/[/\\]+$/, "") || DEFAULT_TESTS_DIR;
309
- const srcDirs = config["src-dir"].map((value) => makeRelativeIfContainsProject(value, projectBase).replace(/[/\\]+$/, "")).filter(Boolean);
711
+ const docsDir = normalizeRelativeDirContract(
712
+ makeRelativeIfContainsProject(config["docs-dir"], projectBase),
713
+ ) || DEFAULT_DOCS_DIR;
714
+ const testsDir = normalizeRelativeDirContract(
715
+ makeRelativeIfContainsProject(config["tests-dir"], projectBase),
716
+ ) || DEFAULT_TESTS_DIR;
717
+ const srcDirs = config["src-dir"]
718
+ .map((value) => normalizeRelativeDirContract(
719
+ makeRelativeIfContainsProject(value, projectBase),
720
+ ))
721
+ .filter((value) => value !== "");
310
722
  return {
311
723
  ...config,
312
724
  "docs-dir": docsDir,
@@ -323,8 +735,12 @@ export function normalizeConfigPaths(projectBase: string, config: UseReqConfig):
323
735
  * @return {Record<string, string>} Placeholder-to-string replacement map including runtime path tokens.
324
736
  * @satisfies REQ-002, REQ-103, REQ-106, REQ-107, CTN-011
325
737
  */
326
- export function buildPromptReplacementPaths(projectBase: string, config: UseReqConfig): Record<string, string> {
327
- const runtimePathContext = buildRuntimePathContext(projectBase, config);
738
+ export function buildPromptReplacementPaths(
739
+ basePath: string,
740
+ contextPath: string,
741
+ config: UseReqConfig,
742
+ ): Record<string, string> {
743
+ const runtimePathContext = buildRuntimePathContext(basePath, contextPath, config);
328
744
  const runtimePathFacts = buildRuntimePathFacts(runtimePathContext);
329
745
  const guidelineEntries = fs.existsSync(runtimePathContext.guidelinesPath)
330
746
  ? fs.readdirSync(runtimePathContext.guidelinesPath)
@@ -333,21 +749,31 @@ export function buildPromptReplacementPaths(projectBase: string, config: UseReqC
333
749
  .sort((left, right) => left.localeCompare(right))
334
750
  : [];
335
751
 
336
- const srcValue = config["src-dir"].map((value) => `\`${value.replace(/[/\\]+$/, "")}/\``).join(", ");
337
- const testValue = `\`${config["tests-dir"].replace(/[/\\]+$/, "")}/\``;
752
+ const normalizedDocsDir = normalizeRelativeDirContract(config["docs-dir"])
753
+ || DEFAULT_DOCS_DIR;
754
+ const normalizedTestsDir = normalizeRelativeDirContract(config["tests-dir"])
755
+ || DEFAULT_TESTS_DIR;
756
+ const normalizedSrcDir = config["src-dir"]
757
+ .map((value) => normalizeRelativeDirContract(value))
758
+ .filter((value) => value !== "");
759
+ const effectiveSrcDir = normalizedSrcDir.length > 0
760
+ ? normalizedSrcDir
761
+ : [...DEFAULT_SRC_DIRS];
762
+ const srcValue = effectiveSrcDir.map((value) => `\`${value}/\``).join(", ");
763
+ const testValue = `\`${normalizedTestsDir}/\``;
338
764
  const guidelinesValue = guidelineEntries.length > 0
339
765
  ? guidelineEntries.map((entry) => `\`${entry}\``).join(", ")
340
- : `\`${runtimePathFacts.guidelines_path}/\``;
766
+ : `\`${runtimePathFacts.guidelines_path}\``;
341
767
 
342
768
  return {
343
- "%%DOC_PATH%%": config["docs-dir"].replace(/[/\\]+$/, ""),
769
+ "%%DOC_PATH%%": normalizedDocsDir,
344
770
  "%%GUIDELINES_FILES%%": guidelinesValue,
345
771
  "%%GUIDELINES_PATH%%": runtimePathFacts.guidelines_path,
346
- "%%TEMPLATE_PATH%%": runtimePathFacts.templates_path,
772
+ "%%TEMPLATE_PATH%%": runtimePathFacts.template_path,
347
773
  "%%SRC_PATHS%%": srcValue,
348
774
  "%%TEST_PATH%%": testValue,
349
775
  "%%PROJECT_BASE%%": runtimePathFacts.base_path,
350
- "%%EXECUTION_PATH%%": runtimePathFacts.execution_path,
776
+ "%%CONTEXT_PATH%%": runtimePathFacts.context_path,
351
777
  "%%INSTALLATION_PATH%%": runtimePathFacts.installation_path,
352
778
  "%%CONFIG_PATH%%": runtimePathFacts.config_path,
353
779
  };