gsd-pi 2.20.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/README.md +12 -0
  2. package/dist/cli.js +21 -18
  3. package/dist/help-text.d.ts +2 -0
  4. package/dist/help-text.js +47 -0
  5. package/dist/loader.js +2 -16
  6. package/dist/mcp-server.d.ts +18 -0
  7. package/dist/mcp-server.js +53 -0
  8. package/dist/onboarding.d.ts +0 -6
  9. package/dist/onboarding.js +0 -28
  10. package/dist/resources/agents/javascript-pro.md +280 -0
  11. package/dist/resources/agents/typescript-pro.md +255 -0
  12. package/dist/resources/extensions/bg-shell/index.ts +14 -2
  13. package/dist/resources/extensions/bg-shell/utilities.ts +14 -0
  14. package/dist/resources/extensions/browser-tools/{core.js → core.ts} +329 -190
  15. package/dist/resources/extensions/gsd/auto-dashboard.ts +2 -1
  16. package/dist/resources/extensions/gsd/auto-prompts.ts +42 -1
  17. package/dist/resources/extensions/gsd/auto-worktree.ts +35 -2
  18. package/dist/resources/extensions/gsd/auto.ts +116 -10
  19. package/dist/resources/extensions/gsd/claude-import.ts +656 -0
  20. package/dist/resources/extensions/gsd/collision-diagnostics.ts +332 -0
  21. package/dist/resources/extensions/gsd/commands.ts +60 -7
  22. package/dist/resources/extensions/gsd/diff-context.ts +220 -0
  23. package/dist/resources/extensions/gsd/docs/claude-marketplace-import.md +214 -0
  24. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -1
  25. package/dist/resources/extensions/gsd/doctor.ts +12 -4
  26. package/dist/resources/extensions/gsd/file-watcher.ts +97 -0
  27. package/dist/resources/extensions/gsd/files.ts +1 -1
  28. package/dist/resources/extensions/gsd/forensics.ts +596 -0
  29. package/dist/resources/extensions/gsd/git-service.ts +2 -1
  30. package/dist/resources/extensions/gsd/github-client.ts +235 -0
  31. package/dist/resources/extensions/gsd/gitignore.ts +1 -0
  32. package/dist/resources/extensions/gsd/marketplace-discovery.ts +507 -0
  33. package/dist/resources/extensions/gsd/mcp-server.ts +87 -0
  34. package/dist/resources/extensions/gsd/namespaced-registry.ts +467 -0
  35. package/dist/resources/extensions/gsd/namespaced-resolver.ts +307 -0
  36. package/dist/resources/extensions/gsd/plugin-importer.ts +410 -0
  37. package/dist/resources/extensions/gsd/preferences.ts +14 -3
  38. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  39. package/dist/resources/extensions/gsd/prompts/forensics.md +71 -0
  40. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  41. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  42. package/dist/resources/extensions/gsd/prompts/system.md +12 -3
  43. package/dist/resources/extensions/gsd/roadmap-slices.ts +1 -1
  44. package/dist/resources/extensions/gsd/session-forensics.ts +5 -5
  45. package/dist/resources/extensions/gsd/tests/claude-import-tui.test.ts +351 -0
  46. package/dist/resources/extensions/gsd/tests/collision-diagnostics.test.ts +705 -0
  47. package/dist/resources/extensions/gsd/tests/context-compression.test.ts +13 -0
  48. package/dist/resources/extensions/gsd/tests/diff-context.test.ts +136 -0
  49. package/dist/resources/extensions/gsd/tests/doctor-git.test.ts +118 -0
  50. package/dist/resources/extensions/gsd/tests/marketplace-discovery.test.ts +202 -0
  51. package/dist/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +91 -0
  52. package/dist/resources/extensions/gsd/tests/namespaced-registry.test.ts +1027 -0
  53. package/dist/resources/extensions/gsd/tests/namespaced-resolver.test.ts +671 -0
  54. package/dist/resources/extensions/gsd/tests/none-mode-gates.test.ts +105 -0
  55. package/dist/resources/extensions/gsd/tests/plugin-importer-live.test.ts +481 -0
  56. package/dist/resources/extensions/gsd/tests/plugin-importer.test.ts +1383 -0
  57. package/dist/resources/extensions/gsd/tests/preferences-git.test.ts +21 -2
  58. package/dist/resources/extensions/gsd/tests/preferences-schema-validation.test.ts +8 -1
  59. package/dist/resources/extensions/gsd/tests/visualizer-data.test.ts +11 -0
  60. package/dist/resources/extensions/gsd/tests/worktree-bugfix.test.ts +120 -0
  61. package/dist/resources/extensions/gsd/token-counter.ts +45 -0
  62. package/dist/resources/extensions/gsd/visualizer-data.ts +2 -2
  63. package/dist/resources/extensions/gsd/worktree-manager.ts +29 -1
  64. package/dist/resources/extensions/gsd/worktree.ts +3 -0
  65. package/dist/resources/extensions/mcporter/index.ts +90 -7
  66. package/dist/resources/extensions/search-the-web/native-search.ts +2 -0
  67. package/dist/resources/extensions/search-the-web/tool-fetch-page.ts +9 -1
  68. package/dist/resources/extensions/search-the-web/url-utils.ts +35 -1
  69. package/dist/resources/extensions/shared/terminal.ts +1 -1
  70. package/dist/resources/extensions/universal-config/discovery.ts +4 -0
  71. package/dist/resources/extensions/universal-config/format.ts +35 -4
  72. package/dist/resources/extensions/universal-config/index.ts +5 -3
  73. package/dist/resources/extensions/universal-config/scanners.ts +65 -2
  74. package/dist/resources/extensions/universal-config/tests/discovery.test.ts +9 -1
  75. package/dist/resources/extensions/universal-config/tests/format.test.ts +22 -6
  76. package/dist/resources/extensions/universal-config/tests/scanners.test.ts +18 -0
  77. package/dist/resources/extensions/universal-config/types.ts +20 -1
  78. package/dist/resources/skills/lint/SKILL.md +141 -0
  79. package/dist/resources/skills/review/SKILL.md +214 -0
  80. package/dist/resources/skills/test/SKILL.md +201 -0
  81. package/dist/tool-bootstrap.js +2 -1
  82. package/dist/wizard.js +2 -0
  83. package/package.json +12 -7
  84. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  85. package/packages/pi-ai/dist/providers/azure-openai-responses.js +12 -1
  86. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  87. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  88. package/packages/pi-ai/dist/providers/openai-responses.js +12 -1
  89. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  90. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +201 -0
  91. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +9 -0
  92. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +762 -0
  93. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +19 -0
  94. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +1 -0
  95. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +9 -0
  96. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +3 -0
  97. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +230 -0
  98. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +87 -0
  99. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +32 -0
  100. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +169 -0
  101. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +21 -0
  102. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +88 -0
  103. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +36 -0
  104. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +21 -0
  105. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +22 -0
  106. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +23 -0
  107. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +8 -0
  108. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +41 -0
  109. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +21 -0
  110. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +4 -0
  111. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +63 -0
  112. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +10 -0
  113. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +5 -0
  114. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +4 -0
  115. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +3 -0
  116. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +46 -0
  117. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +24 -0
  118. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +12 -0
  119. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +63 -0
  120. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +13 -0
  121. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +12 -0
  122. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +2 -0
  123. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +6 -0
  124. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +6 -0
  125. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +2 -0
  126. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +5 -0
  127. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +6 -0
  128. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +13 -0
  129. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +8 -0
  130. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +10 -0
  131. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +5 -0
  132. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +4 -0
  133. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +3 -0
  134. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +46 -0
  135. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +24 -0
  136. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +12 -0
  137. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +63 -0
  138. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +13 -0
  139. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +12 -0
  140. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +2 -0
  141. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +6 -0
  142. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +6 -0
  143. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +2 -0
  144. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +5 -0
  145. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +6 -0
  146. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +13 -0
  147. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +8 -0
  148. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +12 -0
  149. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +12 -0
  150. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +68 -0
  151. package/packages/pi-ai/package.json +3 -0
  152. package/packages/pi-ai/pnpm-lock.yaml +2022 -0
  153. package/packages/pi-ai/src/providers/azure-openai-responses.ts +12 -1
  154. package/packages/pi-ai/src/providers/openai-responses.ts +12 -1
  155. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  156. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  158. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  159. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +1 -0
  160. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/extensions/loader.js +12 -1
  162. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/extensions/loader.test.d.ts +2 -0
  164. package/packages/pi-coding-agent/dist/core/extensions/loader.test.d.ts.map +1 -0
  165. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +113 -0
  166. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -0
  167. package/packages/pi-coding-agent/dist/core/extensions/project-trust.d.ts +4 -0
  168. package/packages/pi-coding-agent/dist/core/extensions/project-trust.d.ts.map +1 -0
  169. package/packages/pi-coding-agent/dist/core/extensions/project-trust.js +42 -0
  170. package/packages/pi-coding-agent/dist/core/extensions/project-trust.js.map +1 -0
  171. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts +1 -0
  172. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/resolve-config-value.js +18 -0
  174. package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.d.ts +2 -0
  176. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.d.ts.map +1 -0
  177. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +114 -0
  178. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -0
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  180. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +8 -2
  181. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  182. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts +2 -0
  183. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  184. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +23 -9
  185. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.d.ts +2 -0
  187. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.d.ts.map +1 -0
  188. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +67 -0
  189. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -0
  190. package/packages/pi-coding-agent/package.json +1 -1
  191. package/packages/pi-coding-agent/pnpm-lock.yaml +454 -0
  192. package/packages/pi-coding-agent/scripts/copy-assets.cjs +24 -0
  193. package/packages/pi-coding-agent/src/core/extensions/index.ts +3 -0
  194. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +141 -0
  195. package/packages/pi-coding-agent/src/core/extensions/loader.ts +14 -1
  196. package/packages/pi-coding-agent/src/core/extensions/project-trust.ts +51 -0
  197. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +132 -0
  198. package/packages/pi-coding-agent/src/core/resolve-config-value.ts +20 -0
  199. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +7 -2
  200. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +98 -0
  201. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +24 -9
  202. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  203. package/packages/pi-tui/dist/tui.js +2 -2
  204. package/packages/pi-tui/dist/tui.js.map +1 -1
  205. package/packages/pi-tui/package.json +3 -1
  206. package/packages/pi-tui/src/tui.ts +2 -2
  207. package/src/resources/agents/javascript-pro.md +280 -0
  208. package/src/resources/agents/typescript-pro.md +255 -0
  209. package/src/resources/extensions/bg-shell/index.ts +14 -2
  210. package/src/resources/extensions/bg-shell/utilities.ts +14 -0
  211. package/src/resources/extensions/browser-tools/{core.js → core.ts} +329 -190
  212. package/src/resources/extensions/gsd/auto-dashboard.ts +2 -1
  213. package/src/resources/extensions/gsd/auto-prompts.ts +42 -1
  214. package/src/resources/extensions/gsd/auto-worktree.ts +35 -2
  215. package/src/resources/extensions/gsd/auto.ts +116 -10
  216. package/src/resources/extensions/gsd/claude-import.ts +656 -0
  217. package/src/resources/extensions/gsd/collision-diagnostics.ts +332 -0
  218. package/src/resources/extensions/gsd/commands.ts +60 -7
  219. package/src/resources/extensions/gsd/diff-context.ts +220 -0
  220. package/src/resources/extensions/gsd/docs/claude-marketplace-import.md +214 -0
  221. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -1
  222. package/src/resources/extensions/gsd/doctor.ts +12 -4
  223. package/src/resources/extensions/gsd/file-watcher.ts +97 -0
  224. package/src/resources/extensions/gsd/files.ts +1 -1
  225. package/src/resources/extensions/gsd/forensics.ts +596 -0
  226. package/src/resources/extensions/gsd/git-service.ts +2 -1
  227. package/src/resources/extensions/gsd/github-client.ts +235 -0
  228. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  229. package/src/resources/extensions/gsd/marketplace-discovery.ts +507 -0
  230. package/src/resources/extensions/gsd/mcp-server.ts +87 -0
  231. package/src/resources/extensions/gsd/namespaced-registry.ts +467 -0
  232. package/src/resources/extensions/gsd/namespaced-resolver.ts +307 -0
  233. package/src/resources/extensions/gsd/plugin-importer.ts +410 -0
  234. package/src/resources/extensions/gsd/preferences.ts +14 -3
  235. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  236. package/src/resources/extensions/gsd/prompts/forensics.md +71 -0
  237. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  238. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  239. package/src/resources/extensions/gsd/prompts/system.md +12 -3
  240. package/src/resources/extensions/gsd/roadmap-slices.ts +1 -1
  241. package/src/resources/extensions/gsd/session-forensics.ts +5 -5
  242. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +351 -0
  243. package/src/resources/extensions/gsd/tests/collision-diagnostics.test.ts +705 -0
  244. package/src/resources/extensions/gsd/tests/context-compression.test.ts +13 -0
  245. package/src/resources/extensions/gsd/tests/diff-context.test.ts +136 -0
  246. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +118 -0
  247. package/src/resources/extensions/gsd/tests/marketplace-discovery.test.ts +202 -0
  248. package/src/resources/extensions/gsd/tests/marketplace-test-fixtures.ts +91 -0
  249. package/src/resources/extensions/gsd/tests/namespaced-registry.test.ts +1027 -0
  250. package/src/resources/extensions/gsd/tests/namespaced-resolver.test.ts +671 -0
  251. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +105 -0
  252. package/src/resources/extensions/gsd/tests/plugin-importer-live.test.ts +481 -0
  253. package/src/resources/extensions/gsd/tests/plugin-importer.test.ts +1383 -0
  254. package/src/resources/extensions/gsd/tests/preferences-git.test.ts +21 -2
  255. package/src/resources/extensions/gsd/tests/preferences-schema-validation.test.ts +8 -1
  256. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +11 -0
  257. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +120 -0
  258. package/src/resources/extensions/gsd/token-counter.ts +45 -0
  259. package/src/resources/extensions/gsd/visualizer-data.ts +2 -2
  260. package/src/resources/extensions/gsd/worktree-manager.ts +29 -1
  261. package/src/resources/extensions/gsd/worktree.ts +3 -0
  262. package/src/resources/extensions/mcporter/index.ts +90 -7
  263. package/src/resources/extensions/search-the-web/native-search.ts +2 -0
  264. package/src/resources/extensions/search-the-web/tool-fetch-page.ts +9 -1
  265. package/src/resources/extensions/search-the-web/url-utils.ts +35 -1
  266. package/src/resources/extensions/shared/terminal.ts +1 -1
  267. package/src/resources/extensions/universal-config/discovery.ts +4 -0
  268. package/src/resources/extensions/universal-config/format.ts +35 -4
  269. package/src/resources/extensions/universal-config/index.ts +5 -3
  270. package/src/resources/extensions/universal-config/scanners.ts +65 -2
  271. package/src/resources/extensions/universal-config/tests/discovery.test.ts +9 -1
  272. package/src/resources/extensions/universal-config/tests/format.test.ts +22 -6
  273. package/src/resources/extensions/universal-config/tests/scanners.test.ts +18 -0
  274. package/src/resources/extensions/universal-config/types.ts +20 -1
  275. package/src/resources/skills/lint/SKILL.md +141 -0
  276. package/src/resources/skills/review/SKILL.md +214 -0
  277. package/src/resources/skills/test/SKILL.md +201 -0
  278. package/dist/resources/extensions/browser-tools/core.d.ts +0 -205
  279. package/src/resources/extensions/browser-tools/core.d.ts +0 -205
@@ -340,7 +340,8 @@ export function updateProgressWidget(
340
340
  let meta = theme.fg("dim", `${done}/${total} slices`);
341
341
 
342
342
  if (activeSliceTasks && activeSliceTasks.total > 0) {
343
- meta += theme.fg("dim", ` · task ${activeSliceTasks.done + 1}/${activeSliceTasks.total}`);
343
+ const taskNum = Math.min(activeSliceTasks.done + 1, activeSliceTasks.total);
344
+ meta += theme.fg("dim", ` · task ${taskNum}/${activeSliceTasks.total}`);
344
345
  }
345
346
 
346
347
  lines.push(truncateToWidth(`${pad}${bar} ${meta}`, width));
@@ -15,11 +15,41 @@ import {
15
15
  relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath,
16
16
  resolveGsdRootFile, relGsdRootFile,
17
17
  } from "./paths.js";
18
- import { resolveSkillDiscoveryMode, resolveInlineLevel } from "./preferences.js";
18
+ import { resolveSkillDiscoveryMode, resolveInlineLevel, loadEffectiveGSDPreferences } from "./preferences.js";
19
19
  import type { GSDState, InlineLevel } from "./types.js";
20
20
  import type { GSDPreferences } from "./preferences.js";
21
21
  import { join } from "node:path";
22
22
  import { existsSync } from "node:fs";
23
+ import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
24
+
25
+ // ─── Executor Constraints ─────────────────────────────────────────────────────
26
+
27
+ /**
28
+ * Format executor context constraints for injection into the plan-slice prompt.
29
+ * Uses the budget engine to compute task count ranges and inline context budgets
30
+ * based on the configured executor model's context window.
31
+ */
32
+ function formatExecutorConstraints(): string {
33
+ let windowTokens: number;
34
+ try {
35
+ const prefs = loadEffectiveGSDPreferences();
36
+ windowTokens = resolveExecutorContextWindow(undefined, prefs?.preferences);
37
+ } catch {
38
+ windowTokens = 200_000; // safe default
39
+ }
40
+ const budgets = computeBudgets(windowTokens);
41
+ const { min, max } = budgets.taskCountRange;
42
+ const execWindowK = Math.round(windowTokens / 1000);
43
+ const perTaskBudgetK = Math.round(budgets.inlineContextBudgetChars / 1000);
44
+ return [
45
+ `## Executor Context Constraints`,
46
+ ``,
47
+ `The agent that executes each task has a **${execWindowK}K token** context window.`,
48
+ `- Recommended task count for this slice: **${min}–${max} tasks**`,
49
+ `- Each task gets ~${perTaskBudgetK}K chars of inline context (plans, code, decisions)`,
50
+ `- Keep individual tasks completable within a single context window — if a task needs more context than fits, split it`,
51
+ ].join("\n");
52
+ }
23
53
 
24
54
  // ─── Inline Helpers ───────────────────────────────────────────────────────
25
55
 
@@ -603,6 +633,9 @@ export async function buildPlanSlicePrompt(
603
633
 
604
634
  const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
605
635
 
636
+ // Build executor context constraints from the budget engine
637
+ const executorContextConstraints = formatExecutorConstraints();
638
+
606
639
  const outputRelPath = relSliceFile(base, mid, sid, "PLAN");
607
640
  return loadPrompt("plan-slice", {
608
641
  workingDirectory: base,
@@ -613,6 +646,7 @@ export async function buildPlanSlicePrompt(
613
646
  outputPath: join(base, outputRelPath),
614
647
  inlinedContext,
615
648
  dependencySummaries: depContent,
649
+ executorContextConstraints,
616
650
  });
617
651
  }
618
652
 
@@ -682,6 +716,12 @@ export async function buildExecuteTaskPrompt(
682
716
  const activeOverrides = await loadActiveOverrides(base);
683
717
  const overridesSection = formatOverridesSection(activeOverrides);
684
718
 
719
+ // Compute verification budget for the executor's context window (issue #707)
720
+ const prefs = loadEffectiveGSDPreferences();
721
+ const contextWindow = resolveExecutorContextWindow(undefined, prefs?.preferences);
722
+ const budgets = computeBudgets(contextWindow);
723
+ const verificationBudget = `~${Math.round(budgets.verificationBudgetChars / 1000)}K chars`;
724
+
685
725
  return loadPrompt("execute-task", {
686
726
  overridesSection,
687
727
  workingDirectory: base,
@@ -696,6 +736,7 @@ export async function buildExecuteTaskPrompt(
696
736
  priorTaskLines: priorLines,
697
737
  taskSummaryPath,
698
738
  inlinedTemplates,
739
+ verificationBudget,
699
740
  });
700
741
  }
701
742
 
@@ -264,11 +264,29 @@ export function isInAutoWorktree(basePath: string): boolean {
264
264
  }
265
265
 
266
266
  /**
267
- * Get the filesystem path for an auto-worktree, or null if it doesn't exist.
267
+ * Get the filesystem path for an auto-worktree, or null if it doesn't exist
268
+ * or is not a valid git worktree.
269
+ *
270
+ * Validates that the path is a real git worktree (has a .git file with a
271
+ * gitdir: pointer) rather than just a stray directory. This prevents
272
+ * mis-detection of leftover directories as active worktrees (#695).
268
273
  */
269
274
  export function getAutoWorktreePath(basePath: string, milestoneId: string): string | null {
270
275
  const p = worktreePath(basePath, milestoneId);
271
- return existsSync(p) ? p : null;
276
+ if (!existsSync(p)) return null;
277
+
278
+ // Validate this is a real git worktree, not a stray directory.
279
+ // A git worktree has a .git *file* (not directory) containing "gitdir: <path>".
280
+ const gitPath = join(p, ".git");
281
+ if (!existsSync(gitPath)) return null;
282
+ try {
283
+ const content = readFileSync(gitPath, "utf8").trim();
284
+ if (!content.startsWith("gitdir: ")) return null;
285
+ } catch {
286
+ return null;
287
+ }
288
+
289
+ return p;
272
290
  }
273
291
 
274
292
  /**
@@ -283,6 +301,21 @@ export function enterAutoWorktree(basePath: string, milestoneId: string): string
283
301
  throw new Error(`Auto-worktree for ${milestoneId} does not exist at ${p}`);
284
302
  }
285
303
 
304
+ // Validate this is a real git worktree, not a stray directory (#695)
305
+ const gitPath = join(p, ".git");
306
+ if (!existsSync(gitPath)) {
307
+ throw new Error(`Auto-worktree path ${p} exists but is not a git worktree (no .git)`);
308
+ }
309
+ try {
310
+ const content = readFileSync(gitPath, "utf8").trim();
311
+ if (!content.startsWith("gitdir: ")) {
312
+ throw new Error(`Auto-worktree path ${p} has a .git but it is not a worktree gitdir pointer`);
313
+ }
314
+ } catch (err) {
315
+ if (err instanceof Error && err.message.includes("worktree")) throw err;
316
+ throw new Error(`Auto-worktree path ${p} exists but .git is unreadable`);
317
+ }
318
+
286
319
  const previousCwd = process.cwd();
287
320
 
288
321
  try {
@@ -40,7 +40,7 @@ import {
40
40
  readUnitRuntimeRecord,
41
41
  writeUnitRuntimeRecord,
42
42
  } from "./unit-runtime.js";
43
- import { resolveAutoSupervisorConfig, resolveModelWithFallbacksForUnit, loadEffectiveGSDPreferences, resolveSkillDiscoveryMode, resolveDynamicRoutingConfig } from "./preferences.js";
43
+ import { resolveAutoSupervisorConfig, resolveModelWithFallbacksForUnit, loadEffectiveGSDPreferences, resolveSkillDiscoveryMode, resolveDynamicRoutingConfig, getIsolationMode } from "./preferences.js";
44
44
  import { sendDesktopNotification } from "./notifications.js";
45
45
  import type { GSDPreferences } from "./preferences.js";
46
46
  import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
@@ -82,7 +82,7 @@ import {
82
82
  import { join } from "node:path";
83
83
  import { sep as pathSep } from "node:path";
84
84
  import { homedir } from "node:os";
85
- import { readdirSync, readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync, statSync } from "node:fs";
85
+ import { readdirSync, readFileSync, existsSync, mkdirSync, writeFileSync, unlinkSync, statSync, cpSync } from "node:fs";
86
86
  import { nativeIsRepo, nativeInit, nativeAddPaths, nativeCommit } from "./native-git-bridge.js";
87
87
  import {
88
88
  autoCommitCurrentBranch,
@@ -146,6 +146,45 @@ import {
146
146
  import { isDbAvailable } from "./gsd-db.js";
147
147
  import { hasPendingCaptures, loadPendingCaptures, countPendingCaptures } from "./captures.js";
148
148
 
149
+ // ─── Worktree → Project Root State Sync ───────────────────────────────────────
150
+ // When running in an auto-worktree, dispatch state (.gsd/ metadata) diverges
151
+ // between the worktree (where work happens) and the project root (where
152
+ // startAutoMode reads initial state on restart). Without syncing, restarting
153
+ // auto-mode reads stale state from the project root and re-dispatches
154
+ // already-completed units.
155
+
156
+ /**
157
+ * Sync dispatch-critical .gsd/ state files from worktree to project root.
158
+ * Only runs when inside an auto-worktree (worktreePath differs from projectRoot).
159
+ * Copies: STATE.md + active milestone directory (roadmap, slice plans, task summaries).
160
+ * Non-fatal — sync failure should never block dispatch.
161
+ */
162
+ function syncStateToProjectRoot(worktreePath: string, projectRoot: string, milestoneId: string | null): void {
163
+ if (!worktreePath || !projectRoot || worktreePath === projectRoot) return;
164
+ if (!milestoneId) return;
165
+
166
+ const wtGsd = join(worktreePath, ".gsd");
167
+ const prGsd = join(projectRoot, ".gsd");
168
+
169
+ // 1. STATE.md — the quick-glance status used by initial deriveState()
170
+ try {
171
+ const src = join(wtGsd, "STATE.md");
172
+ const dst = join(prGsd, "STATE.md");
173
+ if (existsSync(src)) cpSync(src, dst, { force: true });
174
+ } catch { /* non-fatal */ }
175
+
176
+ // 2. Milestone directory — ROADMAP, slice PLANs, task summaries
177
+ // Copy the entire milestone .gsd subtree so deriveState reads current checkboxes
178
+ try {
179
+ const srcMilestone = join(wtGsd, "milestones", milestoneId);
180
+ const dstMilestone = join(prGsd, "milestones", milestoneId);
181
+ if (existsSync(srcMilestone)) {
182
+ mkdirSync(dstMilestone, { recursive: true });
183
+ cpSync(srcMilestone, dstMilestone, { recursive: true, force: true });
184
+ }
185
+ } catch { /* non-fatal */ }
186
+ }
187
+
149
188
  // ─── State ────────────────────────────────────────────────────────────────────
150
189
 
151
190
  let active = false;
@@ -204,12 +243,15 @@ function checkResourcesStale(): string | null {
204
243
 
205
244
  /**
206
245
  * Resolve whether auto-mode should use worktree isolation.
207
- * Returns true for worktree mode (default), false for branch mode.
246
+ * Returns true for worktree mode (default), false for branch and none modes.
208
247
  * Branch mode works directly in the project root — useful for repos
209
248
  * with git submodules where worktrees don't work well (#531).
249
+ * None mode skips all worktree and milestone-branch logic — commits
250
+ * land on the current branch with no isolation (#M001-S02).
210
251
  */
211
- function shouldUseWorktreeIsolation(): boolean {
252
+ export function shouldUseWorktreeIsolation(): boolean {
212
253
  const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
254
+ if (prefs?.isolation === "none") return false;
213
255
  if (prefs?.isolation === "branch") return false;
214
256
  return true; // default: worktree
215
257
  }
@@ -244,6 +286,9 @@ function escapeStaleWorktree(base: string): string {
244
286
  /** Crash recovery prompt — set by startAuto, consumed by first dispatchNextUnit */
245
287
  let pendingCrashRecovery: string | null = null;
246
288
 
289
+ /** Session file path captured at pause — used to synthesize recovery briefing on resume */
290
+ let pausedSessionFile: string | null = null;
291
+
247
292
  /** Dashboard tracking */
248
293
  let autoStartTime: number = 0;
249
294
  let completedUnits: { type: string; id: string; startedAt: number; finishedAt: number }[] = [];
@@ -588,6 +633,7 @@ export async function stopAuto(ctx?: ExtensionContext, pi?: ExtensionAPI): Promi
588
633
  clearActivityLogState();
589
634
  resetProactiveHealing();
590
635
  pendingCrashRecovery = null;
636
+ pausedSessionFile = null;
591
637
  _handlingAgentEnd = false;
592
638
  ctx?.ui.setStatus("gsd-auto", undefined);
593
639
  ctx?.ui.setWidget("gsd-progress", undefined);
@@ -612,6 +658,11 @@ export async function stopAuto(ctx?: ExtensionContext, pi?: ExtensionAPI): Promi
612
658
  export async function pauseAuto(ctx?: ExtensionContext, _pi?: ExtensionAPI): Promise<void> {
613
659
  if (!active) return;
614
660
  clearUnitTimeout();
661
+
662
+ // Capture the current session file before clearing state — used for
663
+ // recovery briefing on resume so the next agent knows what already happened.
664
+ pausedSessionFile = ctx?.sessionManager?.getSessionFile() ?? null;
665
+
615
666
  if (lockBase()) clearLock(lockBase());
616
667
 
617
668
  // Remove SIGTERM handler registered at auto-mode start
@@ -666,7 +717,7 @@ export async function startAuto(
666
717
 
667
718
  // ── Auto-worktree: re-enter worktree on resume if not already inside ──
668
719
  // Skip if already inside a worktree (manual /worktree) to prevent nesting.
669
- // Skip entirely in branch isolation mode (#531).
720
+ // Skip entirely in branch or none isolation mode (#531).
670
721
  if (currentMilestoneId && shouldUseWorktreeIsolation() && originalBasePath && !isInAutoWorktree(basePath) && !detectWorktreeName(basePath) && !detectWorktreeName(originalBasePath)) {
671
722
  try {
672
723
  const existingWtPath = getAutoWorktreePath(originalBasePath, currentMilestoneId);
@@ -709,11 +760,33 @@ export async function startAuto(
709
760
  // Self-heal: clear stale runtime records where artifacts already exist
710
761
  await selfHealRuntimeRecords(basePath, ctx, completedKeySet);
711
762
  invalidateAllCaches();
763
+
764
+ // Synthesize recovery briefing from the paused session so the next agent
765
+ // knows what already happened (reuses crash recovery infrastructure).
766
+ if (pausedSessionFile) {
767
+ const activityDir = join(gsdRoot(basePath), "activity");
768
+ const recovery = synthesizeCrashRecovery(
769
+ basePath,
770
+ currentUnit?.type ?? "unknown",
771
+ currentUnit?.id ?? "unknown",
772
+ pausedSessionFile,
773
+ activityDir,
774
+ );
775
+ if (recovery && recovery.trace.toolCallCount > 0) {
776
+ pendingCrashRecovery = recovery.prompt;
777
+ ctx.ui.notify(
778
+ `Recovered ${recovery.trace.toolCallCount} tool calls from paused session. Resuming with context.`,
779
+ "info",
780
+ );
781
+ }
782
+ pausedSessionFile = null;
783
+ }
784
+
712
785
  await dispatchNextUnit(ctx, pi);
713
786
  return;
714
787
  }
715
788
 
716
- // Ensure git repo exists — GSD needs it for worktree isolation
789
+ // Ensure git repo exists — GSD needs it for commits and state tracking
717
790
  if (!nativeIsRepo(base)) {
718
791
  const mainBranch = loadEffectiveGSDPreferences()?.preferences?.git?.main_branch || "main";
719
792
  nativeInit(base, mainBranch);
@@ -793,6 +866,23 @@ export async function startAuto(
793
866
 
794
867
  let state = await deriveState(base);
795
868
 
869
+ // ── Stale worktree state recovery (#654) ─────────────────────────────────
870
+ // When auto-mode was previously stopped and restarted, the project root's
871
+ // .gsd/ directory may have stale metadata (completed units showing as
872
+ // incomplete). If an auto-worktree exists for the active milestone, it has
873
+ // the current state — re-derive from there to avoid re-dispatching
874
+ // finished work.
875
+ if (
876
+ state.activeMilestone &&
877
+ shouldUseWorktreeIsolation() &&
878
+ !detectWorktreeName(base)
879
+ ) {
880
+ const wtPath = getAutoWorktreePath(base, state.activeMilestone.id);
881
+ if (wtPath) {
882
+ state = await deriveState(wtPath);
883
+ }
884
+ }
885
+
796
886
  // ── Milestone branch recovery (#601) ─────────────────────────────────────
797
887
  // When auto-mode was previously stopped, the milestone branch is preserved
798
888
  // but the worktree is removed. The project root (integration branch) may
@@ -921,7 +1011,9 @@ export async function startAuto(
921
1011
  // of the repo's default (main/master). Idempotent when the branch is the
922
1012
  // same; updates the record when started from a different branch (#300).
923
1013
  if (currentMilestoneId) {
924
- captureIntegrationBranch(base, currentMilestoneId, { commitDocs });
1014
+ if (getIsolationMode() !== "none") {
1015
+ captureIntegrationBranch(base, currentMilestoneId, { commitDocs });
1016
+ }
925
1017
  setActiveMilestoneId(base, currentMilestoneId);
926
1018
  }
927
1019
 
@@ -1183,6 +1275,17 @@ export async function handleAgentEnd(
1183
1275
  // Non-fatal
1184
1276
  }
1185
1277
 
1278
+ // ── Sync worktree state back to project root ──────────────────────────
1279
+ // Ensures that if auto-mode restarts, deriveState(projectRoot) reads
1280
+ // current milestone progress instead of stale pre-worktree state (#654).
1281
+ if (originalBasePath && originalBasePath !== basePath) {
1282
+ try {
1283
+ syncStateToProjectRoot(basePath, originalBasePath, currentMilestoneId);
1284
+ } catch {
1285
+ // Non-fatal — stale state is the existing behavior, sync is an improvement
1286
+ }
1287
+ }
1288
+
1186
1289
  // ── Rewrite-docs completion: resolve overrides and reset circuit breaker ──
1187
1290
  if (currentUnit.type === "rewrite-docs") {
1188
1291
  try {
@@ -1752,8 +1855,11 @@ async function dispatchNextUnit(
1752
1855
  }
1753
1856
  }
1754
1857
  } else {
1755
- // Not in worktree — just capture integration branch for the new milestone
1756
- captureIntegrationBranch(originalBasePath || basePath, mid, { commitDocs: loadEffectiveGSDPreferences()?.preferences?.git?.commit_docs });
1858
+ // Not in worktree — capture integration branch for the new milestone (branch mode only).
1859
+ // In none mode there's no milestone branch to merge back to, so skip.
1860
+ if (getIsolationMode() !== "none") {
1861
+ captureIntegrationBranch(originalBasePath || basePath, mid, { commitDocs: loadEffectiveGSDPreferences()?.preferences?.git?.commit_docs });
1862
+ }
1757
1863
  }
1758
1864
 
1759
1865
  // Prune completed milestone from queue order file
@@ -1849,7 +1955,7 @@ async function dispatchNextUnit(
1849
1955
  try { process.chdir(basePath); } catch { /* best-effort */ }
1850
1956
  }
1851
1957
  }
1852
- } else if (currentMilestoneId && !isInAutoWorktree(basePath)) {
1958
+ } else if (currentMilestoneId && !isInAutoWorktree(basePath) && getIsolationMode() !== "none") {
1853
1959
  // Branch isolation mode (#603): no worktree, but we may be on a milestone/* branch.
1854
1960
  // Squash-merge back to the integration branch (or main) before stopping.
1855
1961
  try {