gsd-pi 2.58.0-dev.778d6ac → 2.58.0-dev.d63175c

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 (628) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +35 -49
  3. package/dist/headless-ui.d.ts +0 -17
  4. package/dist/headless-ui.js +3 -97
  5. package/dist/headless.js +6 -67
  6. package/dist/help-text.js +0 -1
  7. package/dist/onboarding.js +0 -44
  8. package/dist/resource-loader.js +1 -16
  9. package/dist/resources/agents/researcher.md +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +3 -16
  11. package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
  12. package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
  13. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  14. package/dist/resources/extensions/claude-code-cli/partial-builder.js +6 -14
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +36 -59
  16. package/dist/resources/extensions/context7/extension-manifest.json +1 -1
  17. package/dist/resources/extensions/get-secrets-from-user.js +5 -8
  18. package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
  19. package/dist/resources/extensions/google-search/index.js +1 -2
  20. package/dist/resources/extensions/gsd/auto/phases.js +21 -25
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +20 -37
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +2 -17
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +3 -26
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -16
  26. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  27. package/dist/resources/extensions/gsd/auto-recovery.js +5 -13
  28. package/dist/resources/extensions/gsd/auto-start.js +22 -35
  29. package/dist/resources/extensions/gsd/auto-worktree.js +12 -196
  30. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +0 -32
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -80
  32. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -32
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -33
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -44
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +0 -67
  36. package/dist/resources/extensions/gsd/captures.js +4 -56
  37. package/dist/resources/extensions/gsd/db-writer.js +8 -116
  38. package/dist/resources/extensions/gsd/doctor-git-checks.js +0 -28
  39. package/dist/resources/extensions/gsd/doctor-providers.js +1 -2
  40. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +4 -5
  41. package/dist/resources/extensions/gsd/doctor.js +1 -3
  42. package/dist/resources/extensions/gsd/error-classifier.js +10 -13
  43. package/dist/resources/extensions/gsd/extension-manifest.json +1 -16
  44. package/dist/resources/extensions/gsd/forensics.js +20 -123
  45. package/dist/resources/extensions/gsd/git-service.js +1 -23
  46. package/dist/resources/extensions/gsd/gitignore.js +0 -33
  47. package/dist/resources/extensions/gsd/gsd-db.js +9 -36
  48. package/dist/resources/extensions/gsd/guided-flow.js +44 -106
  49. package/dist/resources/extensions/gsd/health-widget-core.js +0 -31
  50. package/dist/resources/extensions/gsd/health-widget.js +0 -17
  51. package/dist/resources/extensions/gsd/index.js +1 -1
  52. package/dist/resources/extensions/gsd/memory-extractor.js +0 -7
  53. package/dist/resources/extensions/gsd/migrate-external.js +1 -8
  54. package/dist/resources/extensions/gsd/model-cost-table.js +0 -18
  55. package/dist/resources/extensions/gsd/model-router.js +1 -35
  56. package/dist/resources/extensions/gsd/native-git-bridge.js +0 -17
  57. package/dist/resources/extensions/gsd/notifications.js +1 -16
  58. package/dist/resources/extensions/gsd/parallel-eligibility.js +2 -13
  59. package/dist/resources/extensions/gsd/parallel-merge.js +5 -78
  60. package/dist/resources/extensions/gsd/parsers-legacy.js +3 -20
  61. package/dist/resources/extensions/gsd/paths.js +0 -43
  62. package/dist/resources/extensions/gsd/preferences-models.js +1 -14
  63. package/dist/resources/extensions/gsd/preferences-types.js +1 -2
  64. package/dist/resources/extensions/gsd/preferences.js +16 -13
  65. package/dist/resources/extensions/gsd/prompt-loader.js +1 -4
  66. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -4
  68. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -3
  71. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  72. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  73. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/plan-slice.md +0 -2
  75. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/triage-captures.md +0 -1
  77. package/dist/resources/extensions/gsd/repo-identity.js +11 -205
  78. package/dist/resources/extensions/gsd/rethink.js +0 -5
  79. package/dist/resources/extensions/gsd/roadmap-slices.js +4 -5
  80. package/dist/resources/extensions/gsd/state.js +27 -85
  81. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +1 -20
  82. package/dist/resources/extensions/gsd/tools/complete-task.js +71 -34
  83. package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -12
  84. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +1 -29
  85. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -14
  86. package/dist/resources/extensions/gsd/triage-resolution.js +7 -22
  87. package/dist/resources/extensions/gsd/undo.js +2 -2
  88. package/dist/resources/extensions/gsd/unit-ownership.js +33 -164
  89. package/dist/resources/extensions/gsd/verdict-parser.js +8 -20
  90. package/dist/resources/extensions/gsd/workflow-manifest.js +5 -24
  91. package/dist/resources/extensions/gsd/workflow-projections.js +63 -95
  92. package/dist/resources/extensions/gsd/workflow-reconcile.js +5 -35
  93. package/dist/resources/extensions/gsd/workspace-index.js +0 -24
  94. package/dist/resources/extensions/gsd/worktree-manager.js +1 -105
  95. package/dist/resources/extensions/gsd/worktree-resolver.js +3 -20
  96. package/dist/resources/extensions/mcp-client/index.js +7 -11
  97. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  98. package/dist/resources/extensions/shared/interview-ui.js +1 -11
  99. package/dist/resources/skills/create-gsd-extension/SKILL.md +3 -5
  100. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +4 -5
  101. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  102. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  103. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +3 -5
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  106. package/dist/web/standalone/.next/build-manifest.json +3 -3
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  109. package/dist/web/standalone/.next/required-server-files.json +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  112. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  128. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/index.html +1 -1
  183. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  184. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  186. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  188. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  189. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  191. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  192. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  195. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  196. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  197. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +9 -0
  198. package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-61d3afac6d0f0ce7.js} +1 -1
  199. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  200. package/dist/web/standalone/server.js +1 -1
  201. package/dist/web-mode.js +1 -2
  202. package/package.json +2 -2
  203. package/packages/native/dist/ast/index.js +5 -9
  204. package/packages/native/dist/ast/types.js +1 -2
  205. package/packages/native/dist/clipboard/index.js +7 -12
  206. package/packages/native/dist/clipboard/types.js +1 -2
  207. package/packages/native/dist/diff/index.js +7 -12
  208. package/packages/native/dist/diff/types.js +1 -2
  209. package/packages/native/dist/fd/index.js +3 -6
  210. package/packages/native/dist/fd/types.js +1 -2
  211. package/packages/native/dist/glob/index.js +5 -9
  212. package/packages/native/dist/glob/types.js +1 -2
  213. package/packages/native/dist/grep/index.js +5 -9
  214. package/packages/native/dist/grep/types.js +1 -2
  215. package/packages/native/dist/gsd-parser/index.js +11 -18
  216. package/packages/native/dist/gsd-parser/types.js +1 -2
  217. package/packages/native/dist/highlight/index.js +7 -12
  218. package/packages/native/dist/highlight/types.js +1 -2
  219. package/packages/native/dist/html/index.js +3 -6
  220. package/packages/native/dist/html/types.js +1 -2
  221. package/packages/native/dist/image/index.js +5 -10
  222. package/packages/native/dist/image/types.js +4 -7
  223. package/packages/native/dist/index.js +17 -70
  224. package/packages/native/dist/json-parse/index.js +8 -13
  225. package/packages/native/dist/native.js +10 -47
  226. package/packages/native/dist/ps/index.js +9 -15
  227. package/packages/native/dist/ps/types.js +1 -2
  228. package/packages/native/dist/stream-process/index.js +7 -12
  229. package/packages/native/dist/text/index.js +14 -24
  230. package/packages/native/dist/text/types.js +2 -5
  231. package/packages/native/dist/truncate/index.js +7 -12
  232. package/packages/native/dist/ttsr/index.js +7 -12
  233. package/packages/native/dist/ttsr/types.js +1 -2
  234. package/packages/native/dist/xxhash/index.js +5 -9
  235. package/packages/native/package.json +19 -19
  236. package/packages/native/src/native.ts +8 -9
  237. package/packages/pi-agent-core/dist/agent-loop.js +2 -3
  238. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  239. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  240. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  241. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  242. package/packages/pi-agent-core/src/agent-loop.ts +2 -3
  243. package/packages/pi-agent-core/src/proxy.ts +1 -1
  244. package/packages/pi-ai/dist/env-api-keys.js +0 -1
  245. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  246. package/packages/pi-ai/dist/index.d.ts +0 -1
  247. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  248. package/packages/pi-ai/dist/index.js +0 -1
  249. package/packages/pi-ai/dist/index.js.map +1 -1
  250. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/anthropic-shared.js +2 -19
  252. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/types.d.ts +3 -3
  254. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/types.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/json-parse.d.ts +0 -3
  257. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  258. package/packages/pi-ai/dist/utils/json-parse.js +1 -24
  259. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  260. package/packages/pi-ai/src/env-api-keys.ts +0 -1
  261. package/packages/pi-ai/src/index.ts +0 -1
  262. package/packages/pi-ai/src/providers/anthropic-shared.ts +2 -17
  263. package/packages/pi-ai/src/types.ts +2 -3
  264. package/packages/pi-ai/src/utils/json-parse.ts +1 -28
  265. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +0 -4
  266. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/agent-session.js +0 -31
  268. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +1 -17
  270. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +2 -62
  272. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/exec.js +1 -3
  275. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +0 -4
  277. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/extensions/index.js +0 -2
  279. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +0 -5
  281. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/extensions/loader.js +0 -5
  283. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  285. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  287. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/lsp/index.js +0 -3
  290. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +0 -3
  293. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/messages.js +2 -31
  296. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/model-resolver.js +0 -1
  299. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +0 -10
  301. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -12
  303. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +0 -6
  305. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/retry-handler.js +1 -48
  307. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -10
  310. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/tools/read.js +4 -13
  313. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  315. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.js +1 -1
  317. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -4
  320. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  321. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +0 -1
  322. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +0 -5
  324. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  325. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -38
  326. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +1 -94
  327. package/packages/pi-coding-agent/src/core/exec.ts +1 -3
  328. package/packages/pi-coding-agent/src/core/extensions/index.ts +0 -4
  329. package/packages/pi-coding-agent/src/core/extensions/loader.ts +0 -5
  330. package/packages/pi-coding-agent/src/core/index.ts +0 -6
  331. package/packages/pi-coding-agent/src/core/lsp/index.ts +0 -3
  332. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +0 -3
  333. package/packages/pi-coding-agent/src/core/messages.ts +2 -29
  334. package/packages/pi-coding-agent/src/core/model-resolver.ts +0 -1
  335. package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -20
  336. package/packages/pi-coding-agent/src/core/retry-handler.ts +1 -52
  337. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +3 -11
  338. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -14
  339. package/packages/pi-coding-agent/src/index.ts +0 -6
  340. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -7
  341. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +0 -6
  342. package/packages/pi-tui/dist/terminal.d.ts +0 -2
  343. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  344. package/packages/pi-tui/dist/terminal.js +0 -9
  345. package/packages/pi-tui/dist/terminal.js.map +1 -1
  346. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  347. package/packages/pi-tui/dist/tui.js +0 -9
  348. package/packages/pi-tui/dist/tui.js.map +1 -1
  349. package/packages/pi-tui/src/terminal.ts +0 -14
  350. package/packages/pi-tui/src/tui.ts +0 -8
  351. package/scripts/ensure-workspace-builds.cjs +14 -45
  352. package/src/resources/agents/researcher.md +1 -1
  353. package/src/resources/extensions/ask-user-questions.ts +3 -21
  354. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  355. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  356. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  357. package/src/resources/extensions/claude-code-cli/partial-builder.ts +6 -13
  358. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +35 -63
  359. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +0 -28
  360. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +1 -108
  361. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  362. package/src/resources/extensions/get-secrets-from-user.ts +5 -8
  363. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  364. package/src/resources/extensions/google-search/index.ts +1 -2
  365. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -1
  366. package/src/resources/extensions/gsd/auto/phases.ts +34 -43
  367. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  368. package/src/resources/extensions/gsd/auto-dashboard.ts +19 -37
  369. package/src/resources/extensions/gsd/auto-dispatch.ts +2 -18
  370. package/src/resources/extensions/gsd/auto-model-selection.ts +5 -26
  371. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -18
  372. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  373. package/src/resources/extensions/gsd/auto-recovery.ts +5 -12
  374. package/src/resources/extensions/gsd/auto-start.ts +26 -35
  375. package/src/resources/extensions/gsd/auto-worktree.ts +9 -190
  376. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +0 -31
  377. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -85
  378. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -38
  379. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +19 -31
  380. package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -50
  381. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +0 -75
  382. package/src/resources/extensions/gsd/captures.ts +3 -63
  383. package/src/resources/extensions/gsd/db-writer.ts +7 -140
  384. package/src/resources/extensions/gsd/doctor-git-checks.ts +0 -26
  385. package/src/resources/extensions/gsd/doctor-providers.ts +1 -2
  386. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +4 -5
  387. package/src/resources/extensions/gsd/doctor.ts +1 -3
  388. package/src/resources/extensions/gsd/error-classifier.ts +11 -14
  389. package/src/resources/extensions/gsd/extension-manifest.json +1 -16
  390. package/src/resources/extensions/gsd/forensics.ts +20 -144
  391. package/src/resources/extensions/gsd/git-service.ts +3 -26
  392. package/src/resources/extensions/gsd/gitignore.ts +0 -33
  393. package/src/resources/extensions/gsd/gsd-db.ts +7 -43
  394. package/src/resources/extensions/gsd/guided-flow.ts +45 -114
  395. package/src/resources/extensions/gsd/health-widget-core.ts +0 -34
  396. package/src/resources/extensions/gsd/health-widget.ts +0 -17
  397. package/src/resources/extensions/gsd/index.ts +0 -1
  398. package/src/resources/extensions/gsd/memory-extractor.ts +0 -8
  399. package/src/resources/extensions/gsd/migrate-external.ts +1 -9
  400. package/src/resources/extensions/gsd/model-cost-table.ts +0 -19
  401. package/src/resources/extensions/gsd/model-router.ts +1 -35
  402. package/src/resources/extensions/gsd/native-git-bridge.ts +0 -17
  403. package/src/resources/extensions/gsd/notifications.ts +0 -16
  404. package/src/resources/extensions/gsd/parallel-eligibility.ts +2 -15
  405. package/src/resources/extensions/gsd/parallel-merge.ts +4 -87
  406. package/src/resources/extensions/gsd/parsers-legacy.ts +3 -22
  407. package/src/resources/extensions/gsd/paths.ts +0 -42
  408. package/src/resources/extensions/gsd/preferences-models.ts +1 -14
  409. package/src/resources/extensions/gsd/preferences-types.ts +1 -2
  410. package/src/resources/extensions/gsd/preferences.ts +15 -13
  411. package/src/resources/extensions/gsd/prompt-loader.ts +1 -4
  412. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  413. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -4
  414. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  415. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  416. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -3
  417. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  418. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  419. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  420. package/src/resources/extensions/gsd/prompts/plan-slice.md +0 -2
  421. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  422. package/src/resources/extensions/gsd/prompts/triage-captures.md +0 -1
  423. package/src/resources/extensions/gsd/repo-identity.ts +11 -186
  424. package/src/resources/extensions/gsd/rethink.ts +0 -6
  425. package/src/resources/extensions/gsd/roadmap-slices.ts +4 -5
  426. package/src/resources/extensions/gsd/state.ts +32 -84
  427. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +0 -29
  428. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +1 -71
  429. package/src/resources/extensions/gsd/tests/captures.test.ts +0 -103
  430. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +0 -27
  431. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +0 -21
  432. package/src/resources/extensions/gsd/tests/db-writer.test.ts +12 -7
  433. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +5 -78
  434. package/src/resources/extensions/gsd/tests/derive-state.test.ts +0 -29
  435. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +0 -40
  436. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +1 -20
  437. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +0 -117
  438. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  439. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -31
  440. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +12 -125
  441. package/src/resources/extensions/gsd/tests/health-widget.test.ts +0 -67
  442. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +1 -111
  443. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +0 -101
  444. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +0 -59
  445. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +0 -110
  446. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  447. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +2 -85
  448. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +0 -34
  449. package/src/resources/extensions/gsd/tests/model-router.test.ts +3 -68
  450. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +0 -28
  451. package/src/resources/extensions/gsd/tests/notifications.test.ts +0 -45
  452. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +1 -33
  453. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +0 -29
  454. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +0 -38
  455. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +0 -117
  456. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +0 -97
  457. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +0 -134
  458. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +1 -2
  459. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +0 -8
  460. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +17 -100
  461. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +1 -4
  462. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +0 -48
  463. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +0 -92
  464. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +2 -4
  465. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +1 -48
  466. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -29
  467. package/src/resources/extensions/gsd/tools/complete-task.ts +74 -36
  468. package/src/resources/extensions/gsd/tools/plan-milestone.ts +1 -13
  469. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +0 -36
  470. package/src/resources/extensions/gsd/tools/validate-milestone.ts +2 -20
  471. package/src/resources/extensions/gsd/triage-resolution.ts +6 -23
  472. package/src/resources/extensions/gsd/types.ts +2 -4
  473. package/src/resources/extensions/gsd/undo.ts +2 -2
  474. package/src/resources/extensions/gsd/unit-ownership.ts +35 -206
  475. package/src/resources/extensions/gsd/verdict-parser.ts +6 -21
  476. package/src/resources/extensions/gsd/workflow-logger.ts +1 -3
  477. package/src/resources/extensions/gsd/workflow-manifest.ts +5 -22
  478. package/src/resources/extensions/gsd/workflow-projections.ts +64 -97
  479. package/src/resources/extensions/gsd/workflow-reconcile.ts +10 -39
  480. package/src/resources/extensions/gsd/workspace-index.ts +0 -30
  481. package/src/resources/extensions/gsd/worktree-manager.ts +1 -120
  482. package/src/resources/extensions/gsd/worktree-resolver.ts +3 -22
  483. package/src/resources/extensions/mcp-client/index.ts +7 -13
  484. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  485. package/src/resources/extensions/shared/interview-ui.ts +1 -12
  486. package/src/resources/skills/create-gsd-extension/SKILL.md +3 -5
  487. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +4 -5
  488. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  489. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  490. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +3 -5
  491. package/dist/resources/extensions/gsd/milestone-validation-gates.js +0 -45
  492. package/dist/resources/extensions/ollama/index.js +0 -112
  493. package/dist/resources/extensions/ollama/model-capabilities.js +0 -115
  494. package/dist/resources/extensions/ollama/ollama-client.js +0 -168
  495. package/dist/resources/extensions/ollama/ollama-commands.js +0 -194
  496. package/dist/resources/extensions/ollama/ollama-discovery.js +0 -69
  497. package/dist/resources/extensions/ollama/ollama-tool.js +0 -184
  498. package/dist/resources/extensions/ollama/types.js +0 -2
  499. package/dist/startup-model-validation.d.ts +0 -39
  500. package/dist/startup-model-validation.js +0 -50
  501. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
  502. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  503. package/packages/native/src/__tests__/module-compat.test.mjs +0 -91
  504. package/packages/pi-agent-core/src/agent-loop.test.ts +0 -45
  505. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +0 -2
  506. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +0 -1
  507. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +0 -25
  508. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +0 -1
  509. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +0 -37
  510. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +0 -1
  511. package/packages/pi-ai/dist/utils/repair-tool-json.js +0 -75
  512. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +0 -1
  513. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +0 -2
  514. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +0 -1
  515. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +0 -73
  516. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +0 -1
  517. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +0 -29
  518. package/packages/pi-ai/src/utils/repair-tool-json.ts +0 -88
  519. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +0 -102
  520. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +0 -6
  521. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +0 -1
  522. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +0 -176
  523. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +0 -1
  524. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +0 -28
  525. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +0 -1
  526. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +0 -37
  527. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +0 -1
  528. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +0 -2
  529. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +0 -1
  530. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +0 -63
  531. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +0 -1
  532. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +0 -19
  533. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +0 -1
  534. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +0 -115
  535. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +0 -1
  536. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +0 -2
  537. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +0 -1
  538. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +0 -109
  539. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +0 -1
  540. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +0 -44
  541. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +0 -1
  542. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +0 -97
  543. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +0 -1
  544. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +0 -2
  545. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +0 -1
  546. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +0 -181
  547. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +0 -1
  548. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +0 -9
  549. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +0 -1
  550. package/packages/pi-coding-agent/dist/core/messages.test.js +0 -86
  551. package/packages/pi-coding-agent/dist/core/messages.test.js.map +0 -1
  552. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +0 -9
  553. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +0 -1
  554. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +0 -193
  555. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +0 -1
  556. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +0 -16
  557. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +0 -1
  558. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +0 -80
  559. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +0 -1
  560. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +0 -236
  561. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +0 -77
  562. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +0 -62
  563. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +0 -134
  564. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +0 -137
  565. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +0 -228
  566. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +0 -118
  567. package/packages/pi-coding-agent/src/core/messages.test.ts +0 -114
  568. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +0 -255
  569. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +0 -92
  570. package/src/resources/extensions/gsd/milestone-validation-gates.ts +0 -56
  571. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +0 -71
  572. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +0 -47
  573. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +0 -192
  574. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +0 -131
  575. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +0 -47
  576. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +0 -127
  577. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +0 -20
  578. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -74
  579. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +0 -140
  580. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -129
  581. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  582. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +0 -164
  583. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +0 -135
  584. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +0 -97
  585. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +0 -107
  586. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +0 -243
  587. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +0 -150
  588. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +0 -959
  589. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +0 -105
  590. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +0 -116
  591. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +0 -159
  592. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +0 -150
  593. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +0 -70
  594. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +0 -297
  595. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +0 -178
  596. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +0 -69
  597. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +0 -157
  598. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +0 -90
  599. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +0 -162
  600. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +0 -233
  601. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +0 -305
  602. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +0 -405
  603. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +0 -257
  604. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +0 -1628
  605. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +0 -106
  606. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +0 -174
  607. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +0 -221
  608. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +0 -289
  609. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +0 -154
  610. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +0 -156
  611. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +0 -82
  612. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +0 -140
  613. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +0 -101
  614. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +0 -95
  615. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +0 -55
  616. package/src/resources/extensions/ollama/index.ts +0 -130
  617. package/src/resources/extensions/ollama/model-capabilities.ts +0 -145
  618. package/src/resources/extensions/ollama/ollama-client.ts +0 -196
  619. package/src/resources/extensions/ollama/ollama-commands.ts +0 -248
  620. package/src/resources/extensions/ollama/ollama-discovery.ts +0 -106
  621. package/src/resources/extensions/ollama/ollama-tool.ts +0 -218
  622. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +0 -162
  623. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +0 -38
  624. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +0 -28
  625. package/src/resources/extensions/ollama/types.ts +0 -130
  626. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +0 -156
  627. /package/dist/web/standalone/.next/static/{R0D4xaIPl5kg93edN7Oo0 → 5DLsjFHdSB6_a1EDQVjr7}/_buildManifest.js +0 -0
  628. /package/dist/web/standalone/.next/static/{R0D4xaIPl5kg93edN7Oo0 → 5DLsjFHdSB6_a1EDQVjr7}/_ssgManifest.js +0 -0
@@ -1,28 +0,0 @@
1
- export interface ExtensionManifest {
2
- id: string;
3
- name: string;
4
- version: string;
5
- description: string;
6
- tier: "core" | "bundled" | "community";
7
- requires: {
8
- platform: string;
9
- };
10
- provides?: {
11
- tools?: string[];
12
- commands?: string[];
13
- hooks?: string[];
14
- shortcuts?: string[];
15
- };
16
- dependencies?: {
17
- extensions?: string[];
18
- runtime?: string[];
19
- };
20
- }
21
- /** Read extension-manifest.json from a directory. Returns null if missing or invalid. */
22
- export declare function readManifest(extensionDir: string): ExtensionManifest | null;
23
- /**
24
- * Given an entry path (e.g. `.../extensions/browser-tools/index.ts`),
25
- * resolve the parent directory and read its manifest.
26
- */
27
- export declare function readManifestFromEntryPath(entryPath: string): ExtensionManifest | null;
28
- //# sourceMappingURL=extension-manifest.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-manifest.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/extension-manifest.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;IACvC,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,YAAY,CAAC,EAAE;QACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACF;AAiBD,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAS3E;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAGrF"}
@@ -1,37 +0,0 @@
1
- // GSD-2 — Extension Manifest: Types and reading for extension-manifest.json
2
- // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
- import { existsSync, readFileSync } from "node:fs";
4
- import { dirname, join } from "node:path";
5
- // ─── Validation ─────────────────────────────────────────────────────────────
6
- function isManifest(data) {
7
- if (typeof data !== "object" || data === null)
8
- return false;
9
- const obj = data;
10
- return (typeof obj.id === "string" &&
11
- typeof obj.name === "string" &&
12
- typeof obj.version === "string" &&
13
- typeof obj.tier === "string");
14
- }
15
- // ─── Reading ────────────────────────────────────────────────────────────────
16
- /** Read extension-manifest.json from a directory. Returns null if missing or invalid. */
17
- export function readManifest(extensionDir) {
18
- const manifestPath = join(extensionDir, "extension-manifest.json");
19
- if (!existsSync(manifestPath))
20
- return null;
21
- try {
22
- const raw = JSON.parse(readFileSync(manifestPath, "utf-8"));
23
- return isManifest(raw) ? raw : null;
24
- }
25
- catch {
26
- return null;
27
- }
28
- }
29
- /**
30
- * Given an entry path (e.g. `.../extensions/browser-tools/index.ts`),
31
- * resolve the parent directory and read its manifest.
32
- */
33
- export function readManifestFromEntryPath(entryPath) {
34
- const dir = dirname(entryPath);
35
- return readManifest(dir);
36
- }
37
- //# sourceMappingURL=extension-manifest.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-manifest.js","sourceRoot":"","sources":["../../../src/core/extensions/extension-manifest.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,4DAA4D;AAE5D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAuB1C,+EAA+E;AAE/E,SAAS,UAAU,CAAC,IAAa;IAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC5D,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,OAAO,CACN,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;QAC1B,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAC5B,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAC/B,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAC5B,CAAC;AACH,CAAC;AAED,+EAA+E;AAE/E,yFAAyF;AACzF,MAAM,UAAU,YAAY,CAAC,YAAoB;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5D,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,SAAiB;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["// GSD-2 — Extension Manifest: Types and reading for extension-manifest.json\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface ExtensionManifest {\n\tid: string;\n\tname: string;\n\tversion: string;\n\tdescription: string;\n\ttier: \"core\" | \"bundled\" | \"community\";\n\trequires: { platform: string };\n\tprovides?: {\n\t\ttools?: string[];\n\t\tcommands?: string[];\n\t\thooks?: string[];\n\t\tshortcuts?: string[];\n\t};\n\tdependencies?: {\n\t\textensions?: string[];\n\t\truntime?: string[];\n\t};\n}\n\n// ─── Validation ─────────────────────────────────────────────────────────────\n\nfunction isManifest(data: unknown): data is ExtensionManifest {\n\tif (typeof data !== \"object\" || data === null) return false;\n\tconst obj = data as Record<string, unknown>;\n\treturn (\n\t\ttypeof obj.id === \"string\" &&\n\t\ttypeof obj.name === \"string\" &&\n\t\ttypeof obj.version === \"string\" &&\n\t\ttypeof obj.tier === \"string\"\n\t);\n}\n\n// ─── Reading ────────────────────────────────────────────────────────────────\n\n/** Read extension-manifest.json from a directory. Returns null if missing or invalid. */\nexport function readManifest(extensionDir: string): ExtensionManifest | null {\n\tconst manifestPath = join(extensionDir, \"extension-manifest.json\");\n\tif (!existsSync(manifestPath)) return null;\n\ttry {\n\t\tconst raw = JSON.parse(readFileSync(manifestPath, \"utf-8\"));\n\t\treturn isManifest(raw) ? raw : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Given an entry path (e.g. `.../extensions/browser-tools/index.ts`),\n * resolve the parent directory and read its manifest.\n */\nexport function readManifestFromEntryPath(entryPath: string): ExtensionManifest | null {\n\tconst dir = dirname(entryPath);\n\treturn readManifest(dir);\n}\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=extension-manifest.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-manifest.test.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/extension-manifest.test.ts"],"names":[],"mappings":""}
@@ -1,63 +0,0 @@
1
- // GSD-2 — Extension Manifest Tests
2
- // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
- import { describe, it } from "node:test";
4
- import assert from "node:assert/strict";
5
- import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
6
- import { join } from "node:path";
7
- import { tmpdir } from "node:os";
8
- import { readManifest, readManifestFromEntryPath } from "./extension-manifest.js";
9
- describe("readManifest", () => {
10
- it("returns null for missing directory", () => {
11
- assert.equal(readManifest("/nonexistent/path"), null);
12
- });
13
- it("returns null for directory without manifest", () => {
14
- const dir = mkdtempSync(join(tmpdir(), "ext-manifest-"));
15
- assert.equal(readManifest(dir), null);
16
- });
17
- it("returns null for invalid JSON", () => {
18
- const dir = mkdtempSync(join(tmpdir(), "ext-manifest-"));
19
- writeFileSync(join(dir, "extension-manifest.json"), "not json{{{", "utf-8");
20
- assert.equal(readManifest(dir), null);
21
- });
22
- it("returns null for manifest missing required fields", () => {
23
- const dir = mkdtempSync(join(tmpdir(), "ext-manifest-"));
24
- writeFileSync(join(dir, "extension-manifest.json"), JSON.stringify({ id: "test", name: "test" }));
25
- assert.equal(readManifest(dir), null);
26
- });
27
- it("returns valid manifest", () => {
28
- const dir = mkdtempSync(join(tmpdir(), "ext-manifest-"));
29
- const manifest = {
30
- id: "test-ext",
31
- name: "Test Extension",
32
- version: "1.0.0",
33
- tier: "bundled",
34
- requires: { platform: ">=2.29.0" },
35
- };
36
- writeFileSync(join(dir, "extension-manifest.json"), JSON.stringify(manifest));
37
- const result = readManifest(dir);
38
- assert.equal(result?.id, "test-ext");
39
- assert.equal(result?.tier, "bundled");
40
- });
41
- });
42
- describe("readManifestFromEntryPath", () => {
43
- it("reads manifest from parent of entry path", () => {
44
- const dir = mkdtempSync(join(tmpdir(), "ext-manifest-"));
45
- const extDir = join(dir, "my-ext");
46
- mkdirSync(extDir);
47
- writeFileSync(join(extDir, "extension-manifest.json"), JSON.stringify({
48
- id: "my-ext",
49
- name: "My Extension",
50
- version: "1.0.0",
51
- tier: "community",
52
- }));
53
- writeFileSync(join(extDir, "index.ts"), "");
54
- const result = readManifestFromEntryPath(join(extDir, "index.ts"));
55
- assert.equal(result?.id, "my-ext");
56
- assert.equal(result?.tier, "community");
57
- });
58
- it("returns null when entry path parent has no manifest", () => {
59
- const dir = mkdtempSync(join(tmpdir(), "ext-manifest-"));
60
- assert.equal(readManifestFromEntryPath(join(dir, "index.ts")), null);
61
- });
62
- });
63
- //# sourceMappingURL=extension-manifest.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-manifest.test.js","sourceRoot":"","sources":["../../../src/core/extensions/extension-manifest.test.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD-2 — Extension Manifest Tests\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { mkdtempSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { readManifest, readManifestFromEntryPath } from \"./extension-manifest.js\";\n\ndescribe(\"readManifest\", () => {\n\tit(\"returns null for missing directory\", () => {\n\t\tassert.equal(readManifest(\"/nonexistent/path\"), null);\n\t});\n\n\tit(\"returns null for directory without manifest\", () => {\n\t\tconst dir = mkdtempSync(join(tmpdir(), \"ext-manifest-\"));\n\t\tassert.equal(readManifest(dir), null);\n\t});\n\n\tit(\"returns null for invalid JSON\", () => {\n\t\tconst dir = mkdtempSync(join(tmpdir(), \"ext-manifest-\"));\n\t\twriteFileSync(join(dir, \"extension-manifest.json\"), \"not json{{{\", \"utf-8\");\n\t\tassert.equal(readManifest(dir), null);\n\t});\n\n\tit(\"returns null for manifest missing required fields\", () => {\n\t\tconst dir = mkdtempSync(join(tmpdir(), \"ext-manifest-\"));\n\t\twriteFileSync(\n\t\t\tjoin(dir, \"extension-manifest.json\"),\n\t\t\tJSON.stringify({ id: \"test\", name: \"test\" }),\n\t\t);\n\t\tassert.equal(readManifest(dir), null);\n\t});\n\n\tit(\"returns valid manifest\", () => {\n\t\tconst dir = mkdtempSync(join(tmpdir(), \"ext-manifest-\"));\n\t\tconst manifest = {\n\t\t\tid: \"test-ext\",\n\t\t\tname: \"Test Extension\",\n\t\t\tversion: \"1.0.0\",\n\t\t\ttier: \"bundled\",\n\t\t\trequires: { platform: \">=2.29.0\" },\n\t\t};\n\t\twriteFileSync(join(dir, \"extension-manifest.json\"), JSON.stringify(manifest));\n\t\tconst result = readManifest(dir);\n\t\tassert.equal(result?.id, \"test-ext\");\n\t\tassert.equal(result?.tier, \"bundled\");\n\t});\n});\n\ndescribe(\"readManifestFromEntryPath\", () => {\n\tit(\"reads manifest from parent of entry path\", () => {\n\t\tconst dir = mkdtempSync(join(tmpdir(), \"ext-manifest-\"));\n\t\tconst extDir = join(dir, \"my-ext\");\n\t\tmkdirSync(extDir);\n\t\twriteFileSync(\n\t\t\tjoin(extDir, \"extension-manifest.json\"),\n\t\t\tJSON.stringify({\n\t\t\t\tid: \"my-ext\",\n\t\t\t\tname: \"My Extension\",\n\t\t\t\tversion: \"1.0.0\",\n\t\t\t\ttier: \"community\",\n\t\t\t}),\n\t\t);\n\t\twriteFileSync(join(extDir, \"index.ts\"), \"\");\n\n\t\tconst result = readManifestFromEntryPath(join(extDir, \"index.ts\"));\n\t\tassert.equal(result?.id, \"my-ext\");\n\t\tassert.equal(result?.tier, \"community\");\n\t});\n\n\tit(\"returns null when entry path parent has no manifest\", () => {\n\t\tconst dir = mkdtempSync(join(tmpdir(), \"ext-manifest-\"));\n\t\tassert.equal(readManifestFromEntryPath(join(dir, \"index.ts\")), null);\n\t});\n});\n"]}
@@ -1,19 +0,0 @@
1
- export interface SortWarning {
2
- declaringId: string;
3
- missingId: string;
4
- message: string;
5
- }
6
- export interface SortResult {
7
- sortedPaths: string[];
8
- warnings: SortWarning[];
9
- }
10
- /**
11
- * Sort extension entry paths in topological dependency-first order using Kahn's BFS algorithm.
12
- *
13
- * - Extensions without manifests are prepended in input order.
14
- * - Missing dependencies produce a structured warning but do not block loading.
15
- * - Cycles produce warnings; cycle participants are appended alphabetically.
16
- * - Self-dependencies are silently ignored.
17
- */
18
- export declare function sortExtensionPaths(paths: string[]): SortResult;
19
- //# sourceMappingURL=extension-sort.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-sort.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/extension-sort.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAgH9D"}
@@ -1,115 +0,0 @@
1
- // GSD-2 — Extension Sort: Topological dependency ordering
2
- // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
- import { readManifestFromEntryPath } from "./extension-manifest.js";
4
- /**
5
- * Sort extension entry paths in topological dependency-first order using Kahn's BFS algorithm.
6
- *
7
- * - Extensions without manifests are prepended in input order.
8
- * - Missing dependencies produce a structured warning but do not block loading.
9
- * - Cycles produce warnings; cycle participants are appended alphabetically.
10
- * - Self-dependencies are silently ignored.
11
- */
12
- export function sortExtensionPaths(paths) {
13
- const warnings = [];
14
- const pathsWithoutId = [];
15
- const idToPath = new Map();
16
- // Step 1: Build ID map
17
- for (const p of paths) {
18
- const manifest = readManifestFromEntryPath(p);
19
- if (!manifest) {
20
- pathsWithoutId.push(p);
21
- }
22
- else {
23
- idToPath.set(manifest.id, p);
24
- }
25
- }
26
- // Step 2: Build graph — inDegree and dependents adjacency
27
- const inDegree = new Map();
28
- const dependents = new Map(); // dep → [ids that depend on dep]
29
- for (const id of idToPath.keys()) {
30
- if (!inDegree.has(id))
31
- inDegree.set(id, 0);
32
- if (!dependents.has(id))
33
- dependents.set(id, []);
34
- }
35
- for (const [id, entryPath] of idToPath) {
36
- const manifest = readManifestFromEntryPath(entryPath);
37
- const rawDeps = manifest?.dependencies?.extensions ?? [];
38
- const deps = Array.isArray(rawDeps) ? rawDeps : [];
39
- for (const depId of deps) {
40
- // Silently ignore self-deps
41
- if (depId === id)
42
- continue;
43
- if (!idToPath.has(depId)) {
44
- // Missing dependency — warn and skip edge
45
- warnings.push({
46
- declaringId: id,
47
- missingId: depId,
48
- message: `Extension '${id}' declares dependency '${depId}' which is not installed — loading anyway`,
49
- });
50
- continue;
51
- }
52
- // Valid edge: id depends on depId → increment inDegree[id], add id to dependents[depId]
53
- inDegree.set(id, (inDegree.get(id) ?? 0) + 1);
54
- const depDependents = dependents.get(depId) ?? [];
55
- depDependents.push(id);
56
- dependents.set(depId, depDependents);
57
- }
58
- }
59
- // Step 3: Kahn's algorithm — start with nodes that have inDegree 0
60
- const sorted = [];
61
- // Ready queue: IDs with inDegree 0, maintained in alphabetical order
62
- const ready = [...idToPath.keys()]
63
- .filter((id) => inDegree.get(id) === 0)
64
- .sort();
65
- while (ready.length > 0) {
66
- const id = ready.shift();
67
- sorted.push(idToPath.get(id));
68
- const deps = dependents.get(id) ?? [];
69
- for (const depId of deps) {
70
- const newDegree = (inDegree.get(depId) ?? 0) - 1;
71
- inDegree.set(depId, newDegree);
72
- if (newDegree === 0) {
73
- // Insert into ready queue maintaining alphabetical order
74
- const insertIdx = ready.findIndex((r) => r > depId);
75
- if (insertIdx === -1) {
76
- ready.push(depId);
77
- }
78
- else {
79
- ready.splice(insertIdx, 0, depId);
80
- }
81
- }
82
- }
83
- }
84
- // Step 4: Cycle handling — any remaining IDs with inDegree > 0
85
- const cycleIds = [...idToPath.keys()]
86
- .filter((id) => (inDegree.get(id) ?? 0) > 0)
87
- .sort();
88
- if (cycleIds.length > 0) {
89
- const cycleSet = new Set(cycleIds);
90
- for (const id of cycleIds) {
91
- const entryPath = idToPath.get(id);
92
- const manifest = readManifestFromEntryPath(entryPath);
93
- const rawDeps = manifest?.dependencies?.extensions ?? [];
94
- const deps = Array.isArray(rawDeps) ? rawDeps : [];
95
- for (const depId of deps) {
96
- if (depId === id)
97
- continue;
98
- if (!cycleSet.has(depId))
99
- continue;
100
- // Both id and depId are in cycle — emit warning
101
- warnings.push({
102
- declaringId: id,
103
- missingId: depId,
104
- message: `Extension '${id}' and '${depId}' form a dependency cycle — loading both anyway (alphabetical order)`,
105
- });
106
- }
107
- sorted.push(entryPath);
108
- }
109
- }
110
- return {
111
- sortedPaths: [...pathsWithoutId, ...sorted],
112
- warnings,
113
- };
114
- }
115
- //# sourceMappingURL=extension-sort.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-sort.js","sourceRoot":"","sources":["../../../src/core/extensions/extension-sort.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,4DAA4D;AAE5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAapE;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAe;IACjD,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE3C,uBAAuB;IACvB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACP,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;IAED,0DAA0D;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC,CAAC,iCAAiC;IAEjF,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,QAAQ,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,QAAQ,EAAE,YAAY,EAAE,UAAU,IAAI,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAEnD,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YAC1B,4BAA4B;YAC5B,IAAI,KAAK,KAAK,EAAE;gBAAE,SAAS;YAE3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,0CAA0C;gBAC1C,QAAQ,CAAC,IAAI,CAAC;oBACb,WAAW,EAAE,EAAE;oBACf,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,cAAc,EAAE,0BAA0B,KAAK,2CAA2C;iBACnG,CAAC,CAAC;gBACH,SAAS;YACV,CAAC;YAED,wFAAwF;YACxF,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAClD,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;IAED,mEAAmE;IACnE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,qEAAqE;IACrE,MAAM,KAAK,GAAa,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;SAC1C,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;SACtC,IAAI,EAAE,CAAC;IAET,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,CAAC;QAE/B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YAC1B,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC/B,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;gBACrB,yDAAyD;gBACzD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;gBACpD,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;oBACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACP,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACnC,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,+DAA+D;IAC/D,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;SACnC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;SAC3C,IAAI,EAAE,CAAC;IAET,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEnC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,QAAQ,EAAE,YAAY,EAAE,UAAU,IAAI,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAEnD,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBAC1B,IAAI,KAAK,KAAK,EAAE;oBAAE,SAAS;gBAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAS;gBAEnC,gDAAgD;gBAChD,QAAQ,CAAC,IAAI,CAAC;oBACb,WAAW,EAAE,EAAE;oBACf,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,cAAc,EAAE,UAAU,KAAK,sEAAsE;iBAC9G,CAAC,CAAC;YACJ,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;IACF,CAAC;IAED,OAAO;QACN,WAAW,EAAE,CAAC,GAAG,cAAc,EAAE,GAAG,MAAM,CAAC;QAC3C,QAAQ;KACR,CAAC;AACH,CAAC","sourcesContent":["// GSD-2 — Extension Sort: Topological dependency ordering\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { readManifestFromEntryPath } from \"./extension-manifest.js\";\n\nexport interface SortWarning {\n\tdeclaringId: string;\n\tmissingId: string;\n\tmessage: string;\n}\n\nexport interface SortResult {\n\tsortedPaths: string[];\n\twarnings: SortWarning[];\n}\n\n/**\n * Sort extension entry paths in topological dependency-first order using Kahn's BFS algorithm.\n *\n * - Extensions without manifests are prepended in input order.\n * - Missing dependencies produce a structured warning but do not block loading.\n * - Cycles produce warnings; cycle participants are appended alphabetically.\n * - Self-dependencies are silently ignored.\n */\nexport function sortExtensionPaths(paths: string[]): SortResult {\n\tconst warnings: SortWarning[] = [];\n\tconst pathsWithoutId: string[] = [];\n\tconst idToPath = new Map<string, string>();\n\n\t// Step 1: Build ID map\n\tfor (const p of paths) {\n\t\tconst manifest = readManifestFromEntryPath(p);\n\t\tif (!manifest) {\n\t\t\tpathsWithoutId.push(p);\n\t\t} else {\n\t\t\tidToPath.set(manifest.id, p);\n\t\t}\n\t}\n\n\t// Step 2: Build graph — inDegree and dependents adjacency\n\tconst inDegree = new Map<string, number>();\n\tconst dependents = new Map<string, string[]>(); // dep → [ids that depend on dep]\n\n\tfor (const id of idToPath.keys()) {\n\t\tif (!inDegree.has(id)) inDegree.set(id, 0);\n\t\tif (!dependents.has(id)) dependents.set(id, []);\n\t}\n\n\tfor (const [id, entryPath] of idToPath) {\n\t\tconst manifest = readManifestFromEntryPath(entryPath);\n\t\tconst rawDeps = manifest?.dependencies?.extensions ?? [];\n\t\tconst deps = Array.isArray(rawDeps) ? rawDeps : [];\n\n\t\tfor (const depId of deps) {\n\t\t\t// Silently ignore self-deps\n\t\t\tif (depId === id) continue;\n\n\t\t\tif (!idToPath.has(depId)) {\n\t\t\t\t// Missing dependency — warn and skip edge\n\t\t\t\twarnings.push({\n\t\t\t\t\tdeclaringId: id,\n\t\t\t\t\tmissingId: depId,\n\t\t\t\t\tmessage: `Extension '${id}' declares dependency '${depId}' which is not installed — loading anyway`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Valid edge: id depends on depId → increment inDegree[id], add id to dependents[depId]\n\t\t\tinDegree.set(id, (inDegree.get(id) ?? 0) + 1);\n\t\t\tconst depDependents = dependents.get(depId) ?? [];\n\t\t\tdepDependents.push(id);\n\t\t\tdependents.set(depId, depDependents);\n\t\t}\n\t}\n\n\t// Step 3: Kahn's algorithm — start with nodes that have inDegree 0\n\tconst sorted: string[] = [];\n\t// Ready queue: IDs with inDegree 0, maintained in alphabetical order\n\tconst ready: string[] = [...idToPath.keys()]\n\t\t.filter((id) => inDegree.get(id) === 0)\n\t\t.sort();\n\n\twhile (ready.length > 0) {\n\t\tconst id = ready.shift()!;\n\t\tsorted.push(idToPath.get(id)!);\n\n\t\tconst deps = dependents.get(id) ?? [];\n\t\tfor (const depId of deps) {\n\t\t\tconst newDegree = (inDegree.get(depId) ?? 0) - 1;\n\t\t\tinDegree.set(depId, newDegree);\n\t\t\tif (newDegree === 0) {\n\t\t\t\t// Insert into ready queue maintaining alphabetical order\n\t\t\t\tconst insertIdx = ready.findIndex((r) => r > depId);\n\t\t\t\tif (insertIdx === -1) {\n\t\t\t\t\tready.push(depId);\n\t\t\t\t} else {\n\t\t\t\t\tready.splice(insertIdx, 0, depId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Step 4: Cycle handling — any remaining IDs with inDegree > 0\n\tconst cycleIds = [...idToPath.keys()]\n\t\t.filter((id) => (inDegree.get(id) ?? 0) > 0)\n\t\t.sort();\n\n\tif (cycleIds.length > 0) {\n\t\tconst cycleSet = new Set(cycleIds);\n\n\t\tfor (const id of cycleIds) {\n\t\t\tconst entryPath = idToPath.get(id)!;\n\t\t\tconst manifest = readManifestFromEntryPath(entryPath);\n\t\t\tconst rawDeps = manifest?.dependencies?.extensions ?? [];\n\t\t\tconst deps = Array.isArray(rawDeps) ? rawDeps : [];\n\n\t\t\tfor (const depId of deps) {\n\t\t\t\tif (depId === id) continue;\n\t\t\t\tif (!cycleSet.has(depId)) continue;\n\n\t\t\t\t// Both id and depId are in cycle — emit warning\n\t\t\t\twarnings.push({\n\t\t\t\t\tdeclaringId: id,\n\t\t\t\t\tmissingId: depId,\n\t\t\t\t\tmessage: `Extension '${id}' and '${depId}' form a dependency cycle — loading both anyway (alphabetical order)`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tsorted.push(entryPath);\n\t\t}\n\t}\n\n\treturn {\n\t\tsortedPaths: [...pathsWithoutId, ...sorted],\n\t\twarnings,\n\t};\n}\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=extension-sort.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-sort.test.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/extension-sort.test.ts"],"names":[],"mappings":""}
@@ -1,109 +0,0 @@
1
- // GSD-2 — Extension Sort Tests
2
- // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
- import { describe, it } from "node:test";
4
- import assert from "node:assert/strict";
5
- import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
6
- import { join } from "node:path";
7
- import { tmpdir } from "node:os";
8
- import { sortExtensionPaths } from "./extension-sort.js";
9
- function createExtDir(base, id, deps) {
10
- const dir = join(base, id);
11
- mkdirSync(dir, { recursive: true });
12
- writeFileSync(join(dir, "extension-manifest.json"), JSON.stringify({
13
- id,
14
- name: id,
15
- version: "1.0.0",
16
- tier: "bundled",
17
- requires: { platform: ">=2.29.0" },
18
- ...(deps ? { dependencies: { extensions: deps } } : {}),
19
- }));
20
- writeFileSync(join(dir, "index.ts"), `export default function() {}`);
21
- return join(dir, "index.ts");
22
- }
23
- describe("sortExtensionPaths", () => {
24
- it("returns empty for empty input", () => {
25
- const result = sortExtensionPaths([]);
26
- assert.deepEqual(result.sortedPaths, []);
27
- assert.deepEqual(result.warnings, []);
28
- });
29
- it("sorts independent extensions alphabetically", () => {
30
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
31
- const pathC = createExtDir(base, "charlie");
32
- const pathA = createExtDir(base, "alpha");
33
- const pathB = createExtDir(base, "bravo");
34
- const result = sortExtensionPaths([pathC, pathA, pathB]);
35
- assert.deepEqual(result.sortedPaths, [pathA, pathB, pathC]);
36
- assert.equal(result.warnings.length, 0);
37
- });
38
- it("sorts dependencies before dependents", () => {
39
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
40
- const pathBase = createExtDir(base, "base-ext");
41
- const pathDependent = createExtDir(base, "dependent-ext", ["base-ext"]);
42
- // Pass dependent first — sort should reorder
43
- const result = sortExtensionPaths([pathDependent, pathBase]);
44
- assert.deepEqual(result.sortedPaths, [pathBase, pathDependent]);
45
- assert.equal(result.warnings.length, 0);
46
- });
47
- it("handles deep dependency chains", () => {
48
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
49
- const pathA = createExtDir(base, "a");
50
- const pathB = createExtDir(base, "b", ["a"]);
51
- const pathC = createExtDir(base, "c", ["b"]);
52
- const result = sortExtensionPaths([pathC, pathB, pathA]);
53
- assert.deepEqual(result.sortedPaths, [pathA, pathB, pathC]);
54
- assert.equal(result.warnings.length, 0);
55
- });
56
- it("warns about missing dependencies but still loads", () => {
57
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
58
- const pathExt = createExtDir(base, "my-ext", ["nonexistent"]);
59
- const result = sortExtensionPaths([pathExt]);
60
- assert.equal(result.sortedPaths.length, 1);
61
- assert.equal(result.sortedPaths[0], pathExt);
62
- assert.equal(result.warnings.length, 1);
63
- assert.match(result.warnings[0].message, /nonexistent.*not installed/);
64
- });
65
- it("warns about cycles but still loads both", () => {
66
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
67
- const pathA = createExtDir(base, "cycle-a", ["cycle-b"]);
68
- const pathB = createExtDir(base, "cycle-b", ["cycle-a"]);
69
- const result = sortExtensionPaths([pathA, pathB]);
70
- assert.equal(result.sortedPaths.length, 2);
71
- assert.ok(result.warnings.length > 0);
72
- assert.ok(result.warnings.some((w) => w.message.includes("cycle")));
73
- });
74
- it("silently ignores self-dependencies", () => {
75
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
76
- const pathExt = createExtDir(base, "self-dep", ["self-dep"]);
77
- const result = sortExtensionPaths([pathExt]);
78
- assert.deepEqual(result.sortedPaths, [pathExt]);
79
- assert.equal(result.warnings.length, 0);
80
- });
81
- it("prepends extensions without manifests", () => {
82
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
83
- const noManifestDir = join(base, "no-manifest");
84
- mkdirSync(noManifestDir, { recursive: true });
85
- writeFileSync(join(noManifestDir, "index.ts"), `export default function() {}`);
86
- const noManifestPath = join(noManifestDir, "index.ts");
87
- const pathWithManifest = createExtDir(base, "with-manifest");
88
- const result = sortExtensionPaths([pathWithManifest, noManifestPath]);
89
- assert.equal(result.sortedPaths[0], noManifestPath);
90
- assert.equal(result.sortedPaths[1], pathWithManifest);
91
- });
92
- it("handles non-array dependencies gracefully", () => {
93
- const base = mkdtempSync(join(tmpdir(), "ext-sort-"));
94
- const dir = join(base, "bad-deps");
95
- mkdirSync(dir, { recursive: true });
96
- writeFileSync(join(dir, "extension-manifest.json"), JSON.stringify({
97
- id: "bad-deps",
98
- name: "bad-deps",
99
- version: "1.0.0",
100
- tier: "bundled",
101
- dependencies: { extensions: "not-an-array" },
102
- }));
103
- writeFileSync(join(dir, "index.ts"), `export default function() {}`);
104
- const result = sortExtensionPaths([join(dir, "index.ts")]);
105
- assert.equal(result.sortedPaths.length, 1);
106
- assert.equal(result.warnings.length, 0);
107
- });
108
- });
109
- //# sourceMappingURL=extension-sort.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extension-sort.test.js","sourceRoot":"","sources":["../../../src/core/extensions/extension-sort.test.ts"],"names":[],"mappings":"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","sourcesContent":["// GSD-2 — Extension Sort Tests\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { mkdtempSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { sortExtensionPaths } from \"./extension-sort.js\";\n\nfunction createExtDir(base: string, id: string, deps?: string[]): string {\n\tconst dir = join(base, id);\n\tmkdirSync(dir, { recursive: true });\n\twriteFileSync(\n\t\tjoin(dir, \"extension-manifest.json\"),\n\t\tJSON.stringify({\n\t\t\tid,\n\t\t\tname: id,\n\t\t\tversion: \"1.0.0\",\n\t\t\ttier: \"bundled\",\n\t\t\trequires: { platform: \">=2.29.0\" },\n\t\t\t...(deps ? { dependencies: { extensions: deps } } : {}),\n\t\t}),\n\t);\n\twriteFileSync(join(dir, \"index.ts\"), `export default function() {}`);\n\treturn join(dir, \"index.ts\");\n}\n\ndescribe(\"sortExtensionPaths\", () => {\n\tit(\"returns empty for empty input\", () => {\n\t\tconst result = sortExtensionPaths([]);\n\t\tassert.deepEqual(result.sortedPaths, []);\n\t\tassert.deepEqual(result.warnings, []);\n\t});\n\n\tit(\"sorts independent extensions alphabetically\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst pathC = createExtDir(base, \"charlie\");\n\t\tconst pathA = createExtDir(base, \"alpha\");\n\t\tconst pathB = createExtDir(base, \"bravo\");\n\n\t\tconst result = sortExtensionPaths([pathC, pathA, pathB]);\n\t\tassert.deepEqual(result.sortedPaths, [pathA, pathB, pathC]);\n\t\tassert.equal(result.warnings.length, 0);\n\t});\n\n\tit(\"sorts dependencies before dependents\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst pathBase = createExtDir(base, \"base-ext\");\n\t\tconst pathDependent = createExtDir(base, \"dependent-ext\", [\"base-ext\"]);\n\n\t\t// Pass dependent first — sort should reorder\n\t\tconst result = sortExtensionPaths([pathDependent, pathBase]);\n\t\tassert.deepEqual(result.sortedPaths, [pathBase, pathDependent]);\n\t\tassert.equal(result.warnings.length, 0);\n\t});\n\n\tit(\"handles deep dependency chains\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst pathA = createExtDir(base, \"a\");\n\t\tconst pathB = createExtDir(base, \"b\", [\"a\"]);\n\t\tconst pathC = createExtDir(base, \"c\", [\"b\"]);\n\n\t\tconst result = sortExtensionPaths([pathC, pathB, pathA]);\n\t\tassert.deepEqual(result.sortedPaths, [pathA, pathB, pathC]);\n\t\tassert.equal(result.warnings.length, 0);\n\t});\n\n\tit(\"warns about missing dependencies but still loads\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst pathExt = createExtDir(base, \"my-ext\", [\"nonexistent\"]);\n\n\t\tconst result = sortExtensionPaths([pathExt]);\n\t\tassert.equal(result.sortedPaths.length, 1);\n\t\tassert.equal(result.sortedPaths[0], pathExt);\n\t\tassert.equal(result.warnings.length, 1);\n\t\tassert.match(result.warnings[0].message, /nonexistent.*not installed/);\n\t});\n\n\tit(\"warns about cycles but still loads both\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst pathA = createExtDir(base, \"cycle-a\", [\"cycle-b\"]);\n\t\tconst pathB = createExtDir(base, \"cycle-b\", [\"cycle-a\"]);\n\n\t\tconst result = sortExtensionPaths([pathA, pathB]);\n\t\tassert.equal(result.sortedPaths.length, 2);\n\t\tassert.ok(result.warnings.length > 0);\n\t\tassert.ok(result.warnings.some((w) => w.message.includes(\"cycle\")));\n\t});\n\n\tit(\"silently ignores self-dependencies\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst pathExt = createExtDir(base, \"self-dep\", [\"self-dep\"]);\n\n\t\tconst result = sortExtensionPaths([pathExt]);\n\t\tassert.deepEqual(result.sortedPaths, [pathExt]);\n\t\tassert.equal(result.warnings.length, 0);\n\t});\n\n\tit(\"prepends extensions without manifests\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst noManifestDir = join(base, \"no-manifest\");\n\t\tmkdirSync(noManifestDir, { recursive: true });\n\t\twriteFileSync(join(noManifestDir, \"index.ts\"), `export default function() {}`);\n\t\tconst noManifestPath = join(noManifestDir, \"index.ts\");\n\n\t\tconst pathWithManifest = createExtDir(base, \"with-manifest\");\n\n\t\tconst result = sortExtensionPaths([pathWithManifest, noManifestPath]);\n\t\tassert.equal(result.sortedPaths[0], noManifestPath);\n\t\tassert.equal(result.sortedPaths[1], pathWithManifest);\n\t});\n\n\tit(\"handles non-array dependencies gracefully\", () => {\n\t\tconst base = mkdtempSync(join(tmpdir(), \"ext-sort-\"));\n\t\tconst dir = join(base, \"bad-deps\");\n\t\tmkdirSync(dir, { recursive: true });\n\t\twriteFileSync(\n\t\t\tjoin(dir, \"extension-manifest.json\"),\n\t\t\tJSON.stringify({\n\t\t\t\tid: \"bad-deps\",\n\t\t\t\tname: \"bad-deps\",\n\t\t\t\tversion: \"1.0.0\",\n\t\t\t\ttier: \"bundled\",\n\t\t\t\tdependencies: { extensions: \"not-an-array\" },\n\t\t\t}),\n\t\t);\n\t\twriteFileSync(join(dir, \"index.ts\"), `export default function() {}`);\n\n\t\tconst result = sortExtensionPaths([join(dir, \"index.ts\")]);\n\t\tassert.equal(result.sortedPaths.length, 1);\n\t\tassert.equal(result.warnings.length, 0);\n\t});\n});\n"]}
@@ -1,44 +0,0 @@
1
- /**
2
- * Image overflow recovery for many-image sessions.
3
- *
4
- * When a conversation accumulates many images (screenshots, file reads, etc.),
5
- * the Anthropic API enforces a stricter per-image dimension limit (2000px) for
6
- * "many-image requests." This module detects the resulting 400 error and
7
- * recovers by stripping older images from the conversation history, preserving
8
- * the most recent ones to maintain session continuity.
9
- *
10
- * @see https://github.com/gsd-build/gsd-2/issues/2874
11
- */
12
- import type { Message } from "@gsd/pi-ai";
13
- /**
14
- * Maximum image dimension (px) that the Anthropic API allows in many-image
15
- * requests. Images at or above this size in a large conversation will be
16
- * rejected with a 400 error. We use 1568 as the safe ceiling (Anthropic's
17
- * recommended max for multi-image requests).
18
- */
19
- export declare const MANY_IMAGE_MAX_DIMENSION = 1568;
20
- /**
21
- * Detect whether an error message is the Anthropic "image dimensions exceed max
22
- * allowed size for many-image requests" 400 error.
23
- */
24
- export declare function isImageDimensionError(errorMessage: string | undefined | null): boolean;
25
- export interface DownsizeResult {
26
- /** Total number of images found in the conversation */
27
- imageCount: number;
28
- /** Whether any images were stripped */
29
- processed: boolean;
30
- /** Number of images that were stripped */
31
- strippedCount: number;
32
- }
33
- /**
34
- * Strip older images from conversation messages to recover from many-image
35
- * dimension errors. Preserves the N most recent images and replaces older ones
36
- * with a text placeholder.
37
- *
38
- * Mutates messages in place (same pattern as replaceMessages/compaction).
39
- *
40
- * Accepts Message[] (the LLM message union) so it works with both
41
- * agent.state.messages and session entries.
42
- */
43
- export declare function downsizeConversationImages(messages: Message[]): DownsizeResult;
44
- //# sourceMappingURL=image-overflow-recovery.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-overflow-recovery.d.ts","sourceRoot":"","sources":["../../src/core/image-overflow-recovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA6B,MAAM,YAAY,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAe7C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAGtF;AAED,MAAM,WAAW,cAAc;IAC9B,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,cAAc,CAsD9E"}
@@ -1,97 +0,0 @@
1
- /**
2
- * Image overflow recovery for many-image sessions.
3
- *
4
- * When a conversation accumulates many images (screenshots, file reads, etc.),
5
- * the Anthropic API enforces a stricter per-image dimension limit (2000px) for
6
- * "many-image requests." This module detects the resulting 400 error and
7
- * recovers by stripping older images from the conversation history, preserving
8
- * the most recent ones to maintain session continuity.
9
- *
10
- * @see https://github.com/gsd-build/gsd-2/issues/2874
11
- */
12
- /**
13
- * Maximum image dimension (px) that the Anthropic API allows in many-image
14
- * requests. Images at or above this size in a large conversation will be
15
- * rejected with a 400 error. We use 1568 as the safe ceiling (Anthropic's
16
- * recommended max for multi-image requests).
17
- */
18
- export const MANY_IMAGE_MAX_DIMENSION = 1568;
19
- /**
20
- * Number of recent images to preserve when stripping old images.
21
- * Keeps the most recent screenshots/images so the model retains visual context
22
- * for the current task.
23
- */
24
- const RECENT_IMAGES_TO_KEEP = 5;
25
- /**
26
- * Regex matching the Anthropic API error for oversized images in many-image requests.
27
- */
28
- const IMAGE_DIMENSION_ERROR_RE = /image.dimensions?.exceed.*max.*allowed.*size.*many.image/i;
29
- /**
30
- * Detect whether an error message is the Anthropic "image dimensions exceed max
31
- * allowed size for many-image requests" 400 error.
32
- */
33
- export function isImageDimensionError(errorMessage) {
34
- if (!errorMessage)
35
- return false;
36
- return IMAGE_DIMENSION_ERROR_RE.test(errorMessage);
37
- }
38
- /**
39
- * Strip older images from conversation messages to recover from many-image
40
- * dimension errors. Preserves the N most recent images and replaces older ones
41
- * with a text placeholder.
42
- *
43
- * Mutates messages in place (same pattern as replaceMessages/compaction).
44
- *
45
- * Accepts Message[] (the LLM message union) so it works with both
46
- * agent.state.messages and session entries.
47
- */
48
- export function downsizeConversationImages(messages) {
49
- // First pass: collect all image locations (message index + content index)
50
- const imageLocations = [];
51
- for (let msgIdx = 0; msgIdx < messages.length; msgIdx++) {
52
- const msg = messages[msgIdx];
53
- if (msg.role === "assistant")
54
- continue;
55
- // UserMessage can have string content; ToolResultMessage always has array
56
- if (msg.role === "user" && typeof msg.content === "string")
57
- continue;
58
- const contentArr = msg.content;
59
- if (!Array.isArray(contentArr))
60
- continue;
61
- for (let contentIdx = 0; contentIdx < contentArr.length; contentIdx++) {
62
- if (contentArr[contentIdx].type === "image") {
63
- imageLocations.push({ msgIdx, contentIdx });
64
- }
65
- }
66
- }
67
- const imageCount = imageLocations.length;
68
- if (imageCount === 0) {
69
- return { imageCount: 0, processed: false, strippedCount: 0 };
70
- }
71
- // Determine which images to strip (all except the N most recent)
72
- const stripCount = Math.max(0, imageCount - RECENT_IMAGES_TO_KEEP);
73
- if (stripCount === 0) {
74
- return { imageCount, processed: false, strippedCount: 0 };
75
- }
76
- const toStrip = imageLocations.slice(0, stripCount);
77
- // Second pass: replace stripped images with text placeholder.
78
- // Process in reverse order to maintain content indices.
79
- for (let i = toStrip.length - 1; i >= 0; i--) {
80
- const { msgIdx, contentIdx } = toStrip[i];
81
- const msg = messages[msgIdx];
82
- if (msg.role === "assistant")
83
- continue;
84
- if (msg.role === "user" && typeof msg.content === "string")
85
- continue;
86
- const contentArr = msg.content;
87
- const imageBlock = contentArr[contentIdx];
88
- const mimeType = imageBlock.mimeType || "image/unknown";
89
- // Replace the image block with a text placeholder
90
- contentArr[contentIdx] = {
91
- type: "text",
92
- text: `[image removed to reduce context size — was ${mimeType}]`,
93
- };
94
- }
95
- return { imageCount, processed: true, strippedCount: stripCount };
96
- }
97
- //# sourceMappingURL=image-overflow-recovery.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-overflow-recovery.js","sourceRoot":"","sources":["../../src/core/image-overflow-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Image overflow recovery for many-image sessions.\n *\n * When a conversation accumulates many images (screenshots, file reads, etc.),\n * the Anthropic API enforces a stricter per-image dimension limit (2000px) for\n * \"many-image requests.\" This module detects the resulting 400 error and\n * recovers by stripping older images from the conversation history, preserving\n * the most recent ones to maintain session continuity.\n *\n * @see https://github.com/gsd-build/gsd-2/issues/2874\n */\n\nimport type { Message, ImageContent, TextContent } from \"@gsd/pi-ai\";\n\n/**\n * Maximum image dimension (px) that the Anthropic API allows in many-image\n * requests. Images at or above this size in a large conversation will be\n * rejected with a 400 error. We use 1568 as the safe ceiling (Anthropic's\n * recommended max for multi-image requests).\n */\nexport const MANY_IMAGE_MAX_DIMENSION = 1568;\n\n/**\n * Number of recent images to preserve when stripping old images.\n * Keeps the most recent screenshots/images so the model retains visual context\n * for the current task.\n */\nconst RECENT_IMAGES_TO_KEEP = 5;\n\n/**\n * Regex matching the Anthropic API error for oversized images in many-image requests.\n */\nconst IMAGE_DIMENSION_ERROR_RE =\n\t/image.dimensions?.exceed.*max.*allowed.*size.*many.image/i;\n\n/**\n * Detect whether an error message is the Anthropic \"image dimensions exceed max\n * allowed size for many-image requests\" 400 error.\n */\nexport function isImageDimensionError(errorMessage: string | undefined | null): boolean {\n\tif (!errorMessage) return false;\n\treturn IMAGE_DIMENSION_ERROR_RE.test(errorMessage);\n}\n\nexport interface DownsizeResult {\n\t/** Total number of images found in the conversation */\n\timageCount: number;\n\t/** Whether any images were stripped */\n\tprocessed: boolean;\n\t/** Number of images that were stripped */\n\tstrippedCount: number;\n}\n\n/**\n * Strip older images from conversation messages to recover from many-image\n * dimension errors. Preserves the N most recent images and replaces older ones\n * with a text placeholder.\n *\n * Mutates messages in place (same pattern as replaceMessages/compaction).\n *\n * Accepts Message[] (the LLM message union) so it works with both\n * agent.state.messages and session entries.\n */\nexport function downsizeConversationImages(messages: Message[]): DownsizeResult {\n\t// First pass: collect all image locations (message index + content index)\n\tconst imageLocations: Array<{ msgIdx: number; contentIdx: number }> = [];\n\n\tfor (let msgIdx = 0; msgIdx < messages.length; msgIdx++) {\n\t\tconst msg = messages[msgIdx];\n\t\tif (msg.role === \"assistant\") continue;\n\n\t\t// UserMessage can have string content; ToolResultMessage always has array\n\t\tif (msg.role === \"user\" && typeof msg.content === \"string\") continue;\n\n\t\tconst contentArr = msg.content as (TextContent | ImageContent)[];\n\t\tif (!Array.isArray(contentArr)) continue;\n\n\t\tfor (let contentIdx = 0; contentIdx < contentArr.length; contentIdx++) {\n\t\t\tif (contentArr[contentIdx].type === \"image\") {\n\t\t\t\timageLocations.push({ msgIdx, contentIdx });\n\t\t\t}\n\t\t}\n\t}\n\n\tconst imageCount = imageLocations.length;\n\tif (imageCount === 0) {\n\t\treturn { imageCount: 0, processed: false, strippedCount: 0 };\n\t}\n\n\t// Determine which images to strip (all except the N most recent)\n\tconst stripCount = Math.max(0, imageCount - RECENT_IMAGES_TO_KEEP);\n\tif (stripCount === 0) {\n\t\treturn { imageCount, processed: false, strippedCount: 0 };\n\t}\n\n\tconst toStrip = imageLocations.slice(0, stripCount);\n\n\t// Second pass: replace stripped images with text placeholder.\n\t// Process in reverse order to maintain content indices.\n\tfor (let i = toStrip.length - 1; i >= 0; i--) {\n\t\tconst { msgIdx, contentIdx } = toStrip[i];\n\t\tconst msg = messages[msgIdx];\n\t\tif (msg.role === \"assistant\") continue;\n\t\tif (msg.role === \"user\" && typeof msg.content === \"string\") continue;\n\n\t\tconst contentArr = msg.content as (TextContent | ImageContent)[];\n\t\tconst imageBlock = contentArr[contentIdx] as ImageContent;\n\t\tconst mimeType = imageBlock.mimeType || \"image/unknown\";\n\n\t\t// Replace the image block with a text placeholder\n\t\t(contentArr as any[])[contentIdx] = {\n\t\t\ttype: \"text\",\n\t\t\ttext: `[image removed to reduce context size — was ${mimeType}]`,\n\t\t} as TextContent;\n\t}\n\n\treturn { imageCount, processed: true, strippedCount: stripCount };\n}\n"]}