gsd-pi 2.50.0 → 2.51.0-dev.7d435fe

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 (681) hide show
  1. package/README.md +6 -4
  2. package/dist/cli.js +26 -0
  3. package/dist/headless-events.d.ts +18 -0
  4. package/dist/headless-events.js +36 -0
  5. package/dist/headless-types.d.ts +28 -0
  6. package/dist/headless-types.js +7 -0
  7. package/dist/headless.d.ts +8 -3
  8. package/dist/headless.js +47 -16
  9. package/dist/help-text.js +16 -5
  10. package/dist/loader.js +4 -0
  11. package/dist/onboarding.js +5 -4
  12. package/dist/remote-questions-config.js +1 -1
  13. package/dist/resource-loader.d.ts +4 -1
  14. package/dist/resource-loader.js +138 -3
  15. package/dist/resources/extensions/async-jobs/async-bash-tool.js +32 -18
  16. package/dist/resources/extensions/bg-shell/interaction.js +3 -1
  17. package/dist/resources/extensions/bg-shell/process-manager.js +4 -1
  18. package/dist/resources/extensions/claude-code-cli/partial-builder.js +5 -0
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
  20. package/dist/resources/extensions/gsd/auto/phases.js +16 -1
  21. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +22 -3
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +98 -53
  24. package/dist/resources/extensions/gsd/auto-observability.js +54 -0
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +37 -76
  26. package/dist/resources/extensions/gsd/auto-prompts.js +57 -0
  27. package/dist/resources/extensions/gsd/auto-recovery.js +21 -25
  28. package/dist/resources/extensions/gsd/auto-start.js +2 -0
  29. package/dist/resources/extensions/gsd/auto-timers.js +24 -2
  30. package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
  31. package/dist/resources/extensions/gsd/auto-utils.js +20 -0
  32. package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
  33. package/dist/resources/extensions/gsd/auto.js +19 -7
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +95 -69
  35. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
  36. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -1
  37. package/dist/resources/extensions/gsd/claude-import.js +60 -9
  38. package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
  39. package/dist/resources/extensions/gsd/commands-config.js +10 -5
  40. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  41. package/dist/resources/extensions/gsd/crash-recovery.js +6 -2
  42. package/dist/resources/extensions/gsd/custom-execution-policy.js +3 -2
  43. package/dist/resources/extensions/gsd/custom-verification.js +3 -1
  44. package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -2
  45. package/dist/resources/extensions/gsd/dashboard-overlay.js +4 -0
  46. package/dist/resources/extensions/gsd/detection.js +595 -9
  47. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +18 -3
  49. package/dist/resources/extensions/gsd/error-classifier.js +105 -0
  50. package/dist/resources/extensions/gsd/files.js +5 -1
  51. package/dist/resources/extensions/gsd/gitignore.js +7 -7
  52. package/dist/resources/extensions/gsd/gsd-db.js +298 -45
  53. package/dist/resources/extensions/gsd/guided-flow.js +10 -0
  54. package/dist/resources/extensions/gsd/init-wizard.js +11 -3
  55. package/dist/resources/extensions/gsd/key-manager.js +7 -16
  56. package/dist/resources/extensions/gsd/memory-store.js +28 -13
  57. package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
  58. package/dist/resources/extensions/gsd/model-router.js +25 -0
  59. package/dist/resources/extensions/gsd/notifications.js +23 -0
  60. package/dist/resources/extensions/gsd/observability-validator.js +422 -0
  61. package/dist/resources/extensions/gsd/preferences-models.js +1 -13
  62. package/dist/resources/extensions/gsd/preferences-skills.js +11 -5
  63. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  64. package/dist/resources/extensions/gsd/preferences-validation.js +25 -0
  65. package/dist/resources/extensions/gsd/preferences.js +16 -13
  66. package/dist/resources/extensions/gsd/prompts/forensics.md +11 -7
  67. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  68. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  69. package/dist/resources/extensions/gsd/provider-error-pause.js +0 -36
  70. package/dist/resources/extensions/gsd/roadmap-mutations.js +110 -0
  71. package/dist/resources/extensions/gsd/rtk-status.js +43 -0
  72. package/dist/resources/extensions/gsd/rule-registry.js +11 -12
  73. package/dist/resources/extensions/gsd/service-tier.js +13 -2
  74. package/dist/resources/extensions/gsd/session-forensics.js +7 -3
  75. package/dist/resources/extensions/gsd/skill-catalog.js +1026 -0
  76. package/dist/resources/extensions/gsd/skill-discovery.js +3 -2
  77. package/dist/resources/extensions/gsd/skill-health.js +2 -2
  78. package/dist/resources/extensions/gsd/skill-telemetry.js +15 -5
  79. package/dist/resources/extensions/gsd/state.js +38 -7
  80. package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
  81. package/dist/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  82. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  83. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -10
  84. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -17
  85. package/dist/resources/extensions/gsd/tools/complete-task.js +7 -18
  86. package/dist/resources/extensions/gsd/tools/plan-milestone.js +26 -17
  87. package/dist/resources/extensions/gsd/tools/plan-slice.js +25 -14
  88. package/dist/resources/extensions/gsd/tools/plan-task.js +21 -11
  89. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +47 -37
  90. package/dist/resources/extensions/gsd/tools/replan-slice.js +49 -38
  91. package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
  92. package/dist/resources/extensions/gsd/undo.js +8 -7
  93. package/dist/resources/extensions/gsd/unit-runtime.js +2 -1
  94. package/dist/resources/extensions/gsd/verification-gate.js +3 -1
  95. package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
  96. package/dist/resources/extensions/remote-questions/config.js +1 -1
  97. package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
  98. package/dist/resources/extensions/search-the-web/native-search.js +1 -1
  99. package/dist/resources/extensions/search-the-web/provider.js +1 -1
  100. package/dist/resources/extensions/shared/rtk-session-stats.js +189 -0
  101. package/dist/resources/extensions/shared/rtk.js +100 -0
  102. package/dist/rtk.d.ts +52 -0
  103. package/dist/rtk.js +332 -0
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  106. package/dist/web/standalone/.next/build-manifest.json +4 -4
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  109. package/dist/web/standalone/.next/required-server-files.json +3 -3
  110. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  111. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  112. package/dist/web/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  115. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  123. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/experimental/route.js +3 -0
  161. package/dist/web/standalone/.next/server/app/api/experimental/route.js.nft.json +1 -0
  162. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -0
  163. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/preferences/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -26
  203. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  213. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  216. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  219. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  222. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  225. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  231. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  233. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  236. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js.nft.json +1 -1
  237. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  239. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  242. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  243. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  249. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/app/index.html +1 -1
  257. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  258. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  259. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  260. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  261. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  262. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  263. package/dist/web/standalone/.next/server/app/page.js +2 -2
  264. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  267. package/dist/web/standalone/.next/server/chunks/2229.js +12 -0
  268. package/dist/web/standalone/.next/server/chunks/2331.js +25 -0
  269. package/dist/web/standalone/.next/server/chunks/{741.js → 4741.js} +1 -1
  270. package/dist/web/standalone/.next/server/chunks/5822.js +2 -0
  271. package/dist/web/standalone/.next/server/chunks/7471.js +13 -0
  272. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  273. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  274. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  275. package/dist/web/standalone/.next/server/middleware.js +3 -3
  276. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  277. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  278. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  279. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  280. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  281. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  282. package/dist/web/standalone/.next/static/RqOU-jOv9uZ1Q03P6L6nn/_buildManifest.js +1 -0
  283. package/dist/web/standalone/.next/static/chunks/{485.243af25f0cdf50d6.js → 2008.817d0885545aaea9.js} +6 -6
  284. package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +9 -0
  285. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-c4cc189e7b117ea2.js +1 -0
  286. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  287. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-c4cc189e7b117ea2.js +1 -0
  288. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-c4cc189e7b117ea2.js +1 -0
  289. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  290. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  291. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-c4cc189e7b117ea2.js +1 -0
  292. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-c4cc189e7b117ea2.js +1 -0
  293. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-c4cc189e7b117ea2.js +1 -0
  294. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-c4cc189e7b117ea2.js +1 -0
  295. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-c4cc189e7b117ea2.js +1 -0
  296. package/dist/web/standalone/.next/static/chunks/app/api/experimental/route-c4cc189e7b117ea2.js +1 -0
  297. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-c4cc189e7b117ea2.js +1 -0
  298. package/dist/web/standalone/.next/static/chunks/app/api/files/route-c4cc189e7b117ea2.js +1 -0
  299. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-c4cc189e7b117ea2.js +1 -0
  300. package/dist/web/standalone/.next/static/chunks/app/api/git/route-c4cc189e7b117ea2.js +1 -0
  301. package/dist/web/standalone/.next/static/chunks/app/api/history/route-c4cc189e7b117ea2.js +1 -0
  302. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-c4cc189e7b117ea2.js +1 -0
  303. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-c4cc189e7b117ea2.js +1 -0
  304. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-c4cc189e7b117ea2.js +1 -0
  305. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-c4cc189e7b117ea2.js +1 -0
  306. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-c4cc189e7b117ea2.js +1 -0
  307. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-c4cc189e7b117ea2.js +1 -0
  308. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-c4cc189e7b117ea2.js +1 -0
  309. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-c4cc189e7b117ea2.js +1 -0
  310. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-c4cc189e7b117ea2.js +1 -0
  311. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-c4cc189e7b117ea2.js +1 -0
  312. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-c4cc189e7b117ea2.js +1 -0
  313. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-c4cc189e7b117ea2.js +1 -0
  314. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-c4cc189e7b117ea2.js +1 -0
  315. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-c4cc189e7b117ea2.js +1 -0
  316. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-c4cc189e7b117ea2.js +1 -0
  317. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-c4cc189e7b117ea2.js +1 -0
  318. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-c4cc189e7b117ea2.js +1 -0
  319. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-c4cc189e7b117ea2.js +1 -0
  320. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-c4cc189e7b117ea2.js +1 -0
  321. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-c4cc189e7b117ea2.js +1 -0
  322. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-c4cc189e7b117ea2.js +1 -0
  323. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-c4cc189e7b117ea2.js +1 -0
  324. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-c4cc189e7b117ea2.js +1 -0
  325. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-c4cc189e7b117ea2.js +1 -0
  326. package/dist/web/standalone/.next/static/chunks/app/api/update/route-c4cc189e7b117ea2.js +1 -0
  327. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-c4cc189e7b117ea2.js +1 -0
  328. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  329. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  330. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  331. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-c4cc189e7b117ea2.js +1 -0
  332. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-c4cc189e7b117ea2.js +1 -0
  333. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  334. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-c4cc189e7b117ea2.js +1 -0
  335. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-c4cc189e7b117ea2.js +1 -0
  336. package/dist/web/standalone/.next/static/chunks/webpack-024d82be84800e52.js +1 -0
  337. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  338. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  339. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  340. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  341. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  342. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  343. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  344. package/dist/web/standalone/server.js +1 -1
  345. package/dist/wizard.js +4 -1
  346. package/package.json +2 -2
  347. package/packages/pi-ai/dist/models.d.ts +14 -3
  348. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  349. package/packages/pi-ai/dist/models.js +53 -10
  350. package/packages/pi-ai/dist/models.js.map +1 -1
  351. package/packages/pi-ai/dist/models.test.js +102 -1
  352. package/packages/pi-ai/dist/models.test.js.map +1 -1
  353. package/packages/pi-ai/dist/types.d.ts +31 -0
  354. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  355. package/packages/pi-ai/dist/types.js.map +1 -1
  356. package/packages/pi-ai/src/models.test.ts +114 -1
  357. package/packages/pi-ai/src/models.ts +70 -13
  358. package/packages/pi-ai/src/types.ts +32 -1
  359. package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
  360. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/cli/args.js +3 -0
  362. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
  364. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -0
  366. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts +3 -1
  368. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/bash-executor.js +15 -2
  370. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  372. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  375. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/extensions/runner.js +13 -0
  377. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +19 -1
  379. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/extensions/wrapper.d.ts.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js +8 -0
  383. package/packages/pi-coding-agent/dist/core/extensions/wrapper.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
  386. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/package-manager.js +8 -1
  389. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/skills.d.ts +11 -1
  391. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/skills.js +30 -8
  393. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  396. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
  398. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
  399. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
  400. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
  403. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  404. package/packages/pi-coding-agent/dist/index.d.ts +3 -3
  405. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  406. package/packages/pi-coding-agent/dist/index.js +1 -1
  407. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  408. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  409. package/packages/pi-coding-agent/dist/main.js +5 -3
  410. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  411. package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
  412. package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  413. package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  415. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +3 -2
  416. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  417. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  418. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
  419. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +6 -4
  422. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +5 -0
  424. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +12 -0
  426. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  428. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +2 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  430. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
  431. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
  433. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
  435. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
  437. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
  439. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
  440. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
  441. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
  442. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
  443. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  444. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  445. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  446. package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
  447. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  448. package/packages/pi-coding-agent/package.json +1 -1
  449. package/packages/pi-coding-agent/src/cli/args.ts +4 -0
  450. package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
  451. package/packages/pi-coding-agent/src/core/bash-executor.ts +15 -3
  452. package/packages/pi-coding-agent/src/core/extensions/index.ts +2 -0
  453. package/packages/pi-coding-agent/src/core/extensions/runner.ts +18 -0
  454. package/packages/pi-coding-agent/src/core/extensions/types.ts +21 -0
  455. package/packages/pi-coding-agent/src/core/extensions/wrapper.ts +9 -0
  456. package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
  457. package/packages/pi-coding-agent/src/core/package-manager.ts +10 -1
  458. package/packages/pi-coding-agent/src/core/skills.ts +35 -10
  459. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  460. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
  461. package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
  462. package/packages/pi-coding-agent/src/index.ts +7 -0
  463. package/packages/pi-coding-agent/src/main.ts +5 -3
  464. package/packages/pi-coding-agent/src/modes/index.ts +8 -1
  465. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +3 -2
  466. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
  467. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +6 -4
  468. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +15 -0
  469. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +2 -1
  470. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
  471. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
  472. package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  473. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
  474. package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
  475. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  476. package/pkg/dist/modes/interactive/theme/themes.js +2 -1
  477. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  478. package/pkg/package.json +1 -1
  479. package/scripts/postinstall.js +163 -6
  480. package/src/resources/extensions/async-jobs/async-bash-tool.ts +25 -12
  481. package/src/resources/extensions/bg-shell/interaction.ts +3 -1
  482. package/src/resources/extensions/bg-shell/process-manager.ts +4 -1
  483. package/src/resources/extensions/claude-code-cli/partial-builder.ts +5 -0
  484. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
  485. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +105 -0
  486. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
  487. package/src/resources/extensions/gsd/auto/phases.ts +15 -1
  488. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  489. package/src/resources/extensions/gsd/auto-dashboard.ts +31 -3
  490. package/src/resources/extensions/gsd/auto-dispatch.ts +102 -50
  491. package/src/resources/extensions/gsd/auto-observability.ts +72 -0
  492. package/src/resources/extensions/gsd/auto-post-unit.ts +56 -83
  493. package/src/resources/extensions/gsd/auto-prompts.ts +48 -0
  494. package/src/resources/extensions/gsd/auto-recovery.ts +19 -26
  495. package/src/resources/extensions/gsd/auto-start.ts +2 -0
  496. package/src/resources/extensions/gsd/auto-timers.ts +25 -1
  497. package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
  498. package/src/resources/extensions/gsd/auto-utils.ts +25 -0
  499. package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
  500. package/src/resources/extensions/gsd/auto.ts +20 -7
  501. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +115 -72
  502. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
  503. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -1
  504. package/src/resources/extensions/gsd/claude-import.ts +58 -9
  505. package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
  506. package/src/resources/extensions/gsd/commands-config.ts +11 -5
  507. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  508. package/src/resources/extensions/gsd/crash-recovery.ts +6 -2
  509. package/src/resources/extensions/gsd/custom-execution-policy.ts +3 -2
  510. package/src/resources/extensions/gsd/custom-verification.ts +3 -1
  511. package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -2
  512. package/src/resources/extensions/gsd/dashboard-overlay.ts +7 -0
  513. package/src/resources/extensions/gsd/detection.ts +668 -9
  514. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
  515. package/src/resources/extensions/gsd/docs/preferences-reference.md +18 -3
  516. package/src/resources/extensions/gsd/error-classifier.ts +139 -0
  517. package/src/resources/extensions/gsd/files.ts +6 -1
  518. package/src/resources/extensions/gsd/gitignore.ts +7 -7
  519. package/src/resources/extensions/gsd/gsd-db.ts +355 -63
  520. package/src/resources/extensions/gsd/guided-flow.ts +11 -0
  521. package/src/resources/extensions/gsd/init-wizard.ts +11 -3
  522. package/src/resources/extensions/gsd/key-manager.ts +7 -16
  523. package/src/resources/extensions/gsd/memory-store.ts +29 -18
  524. package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
  525. package/src/resources/extensions/gsd/model-router.ts +25 -0
  526. package/src/resources/extensions/gsd/notifications.ts +23 -0
  527. package/src/resources/extensions/gsd/observability-validator.ts +456 -0
  528. package/src/resources/extensions/gsd/preferences-models.ts +1 -13
  529. package/src/resources/extensions/gsd/preferences-skills.ts +11 -5
  530. package/src/resources/extensions/gsd/preferences-types.ts +20 -0
  531. package/src/resources/extensions/gsd/preferences-validation.ts +26 -0
  532. package/src/resources/extensions/gsd/preferences.ts +15 -13
  533. package/src/resources/extensions/gsd/prompts/forensics.md +11 -7
  534. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  535. package/src/resources/extensions/gsd/prompts/validate-milestone.md +6 -1
  536. package/src/resources/extensions/gsd/provider-error-pause.ts +0 -48
  537. package/src/resources/extensions/gsd/roadmap-mutations.ts +134 -0
  538. package/src/resources/extensions/gsd/rtk-status.ts +53 -0
  539. package/src/resources/extensions/gsd/rule-registry.ts +11 -12
  540. package/src/resources/extensions/gsd/service-tier.ts +14 -2
  541. package/src/resources/extensions/gsd/session-forensics.ts +7 -3
  542. package/src/resources/extensions/gsd/skill-catalog.ts +1085 -0
  543. package/src/resources/extensions/gsd/skill-discovery.ts +3 -2
  544. package/src/resources/extensions/gsd/skill-health.ts +2 -2
  545. package/src/resources/extensions/gsd/skill-telemetry.ts +15 -5
  546. package/src/resources/extensions/gsd/state.ts +38 -7
  547. package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +2 -0
  548. package/src/resources/extensions/gsd/templates/milestone-validation.md +12 -0
  549. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +16 -0
  550. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +2 -2
  551. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +68 -0
  552. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
  553. package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
  554. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
  555. package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
  556. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +2 -2
  557. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  558. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
  559. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  560. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +5 -3
  561. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +33 -0
  562. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +39 -10
  563. package/src/resources/extensions/gsd/tests/detection.test.ts +839 -1
  564. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +28 -9
  565. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
  566. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
  567. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
  568. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +97 -0
  569. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  570. package/src/resources/extensions/gsd/tests/git-service.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  572. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +63 -0
  573. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
  574. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
  575. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
  576. package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
  577. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  578. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  579. package/src/resources/extensions/gsd/tests/model-router.test.ts +40 -0
  580. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
  581. package/src/resources/extensions/gsd/tests/notifications.test.ts +28 -6
  582. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
  583. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +474 -0
  584. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
  585. package/src/resources/extensions/gsd/tests/preferences.test.ts +51 -1
  586. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
  587. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +40 -0
  588. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +6 -6
  589. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
  590. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
  591. package/src/resources/extensions/gsd/tests/retry-diagnostic-reasoning.test.ts +161 -0
  592. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +4 -5
  593. package/src/resources/extensions/gsd/tests/rewrite-count-persist.test.ts +82 -0
  594. package/src/resources/extensions/gsd/tests/run-uat.test.ts +146 -0
  595. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +12 -12
  596. package/src/resources/extensions/gsd/tests/skill-catalog.test.ts +193 -0
  597. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +56 -21
  598. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
  599. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +2 -2
  600. package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
  601. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
  602. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
  603. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
  604. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -14
  605. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -21
  606. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -22
  607. package/src/resources/extensions/gsd/tools/plan-milestone.ts +28 -18
  608. package/src/resources/extensions/gsd/tools/plan-slice.ts +28 -16
  609. package/src/resources/extensions/gsd/tools/plan-task.ts +24 -12
  610. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +54 -42
  611. package/src/resources/extensions/gsd/tools/replan-slice.ts +53 -40
  612. package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
  613. package/src/resources/extensions/gsd/types.ts +2 -0
  614. package/src/resources/extensions/gsd/undo.ts +8 -7
  615. package/src/resources/extensions/gsd/unit-runtime.ts +2 -1
  616. package/src/resources/extensions/gsd/verification-gate.ts +3 -1
  617. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  618. package/src/resources/extensions/remote-questions/config.ts +1 -1
  619. package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
  620. package/src/resources/extensions/search-the-web/native-search.ts +1 -1
  621. package/src/resources/extensions/search-the-web/provider.ts +1 -1
  622. package/src/resources/extensions/shared/rtk-session-stats.ts +249 -0
  623. package/src/resources/extensions/shared/rtk.ts +120 -0
  624. package/dist/web/standalone/.next/server/chunks/229.js +0 -12
  625. package/dist/web/standalone/.next/server/chunks/441.js +0 -2
  626. package/dist/web/standalone/.next/server/chunks/471.js +0 -13
  627. package/dist/web/standalone/.next/static/MQOhBnkC_TLtNn_JvZWDj/_buildManifest.js +0 -1
  628. package/dist/web/standalone/.next/static/chunks/4024.7c75ac378de0f2b5.js +0 -9
  629. package/dist/web/standalone/.next/static/chunks/app/_global-error/page-d83ba70a25a85472.js +0 -1
  630. package/dist/web/standalone/.next/static/chunks/app/api/boot/route-d83ba70a25a85472.js +0 -1
  631. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/route-d83ba70a25a85472.js +0 -1
  632. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/route-d83ba70a25a85472.js +0 -1
  633. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +0 -1
  634. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +0 -1
  635. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +0 -1
  636. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +0 -1
  637. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +0 -1
  638. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +0 -1
  639. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +0 -1
  640. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +0 -1
  641. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +0 -1
  642. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +0 -1
  673. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +0 -1
  674. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  675. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +0 -1
  676. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +0 -1
  677. package/dist/web/standalone/.next/static/chunks/webpack-2473ce2c3879fff4.js +0 -1
  678. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +0 -1
  679. package/packages/pi-ai/pnpm-lock.yaml +0 -2022
  680. package/packages/pi-coding-agent/pnpm-lock.yaml +0 -454
  681. /package/dist/web/standalone/.next/static/{MQOhBnkC_TLtNn_JvZWDj → RqOU-jOv9uZ1Q03P6L6nn}/_ssgManifest.js +0 -0
@@ -6,7 +6,7 @@
6
6
  * flow to show when entering a project directory.
7
7
  */
8
8
 
9
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
9
+ import { existsSync, openSync, readSync, closeSync, readdirSync, readFileSync, statSync } from "node:fs";
10
10
  import { join } from "node:path";
11
11
  import { homedir } from "node:os";
12
12
  import { gsdRoot } from "./paths.js";
@@ -48,6 +48,9 @@ export interface V2Detection {
48
48
  hasContext: boolean;
49
49
  }
50
50
 
51
+ /** Apple platform SDKROOTs found in Xcode project.pbxproj files. */
52
+ export type XcodePlatform = "iphoneos" | "macosx" | "watchos" | "appletvos" | "xros";
53
+
51
54
  export interface ProjectSignals {
52
55
  /** Detected project/package files */
53
56
  detectedFiles: string[];
@@ -57,6 +60,8 @@ export interface ProjectSignals {
57
60
  isMonorepo: boolean;
58
61
  /** Primary language hint */
59
62
  primaryLanguage?: string;
63
+ /** Apple platform SDKROOTs detected from *.xcodeproj/project.pbxproj */
64
+ xcodePlatforms: XcodePlatform[];
60
65
  /** Has existing CI configuration? */
61
66
  hasCI: boolean;
62
67
  /** Has existing test setup? */
@@ -97,10 +102,81 @@ export const PROJECT_FILES = [
97
102
  "project.yml",
98
103
  ".xcodeproj",
99
104
  ".xcworkspace",
100
- // Docker
105
+ // Cloud platform config files
106
+ "firebase.json",
107
+ "cdk.json",
108
+ "samconfig.toml",
109
+ "serverless.yml",
110
+ "serverless.yaml",
111
+ "azure-pipelines.yml",
112
+ // Database / ORM config files
113
+ "prisma/schema.prisma",
114
+ "supabase/config.toml",
115
+ "drizzle.config.ts",
116
+ "drizzle.config.js",
117
+ "redis.conf",
118
+ // React Native markers
119
+ "metro.config.js",
120
+ "metro.config.ts",
121
+ "react-native.config.js",
122
+ // Frontend framework config files
123
+ "angular.json",
124
+ "next.config.js",
125
+ "next.config.ts",
126
+ "next.config.mjs",
127
+ "nuxt.config.ts",
128
+ "nuxt.config.js",
129
+ "svelte.config.js",
130
+ "svelte.config.ts",
131
+ // Vue CLI config files
132
+ "vue.config.js",
133
+ "vue.config.ts",
134
+ // Frontend tooling
135
+ "tailwind.config.js",
136
+ "tailwind.config.ts",
137
+ "tailwind.config.mjs",
138
+ "tailwind.config.cjs",
139
+ // Android project markers
140
+ "app/build.gradle",
141
+ "app/build.gradle.kts",
142
+ // Container / DevOps config files
101
143
  "Dockerfile",
144
+ "docker-compose.yml",
145
+ "docker-compose.yaml",
146
+ // Infrastructure as Code
147
+ "main.tf",
148
+ // Kubernetes / Helm markers
149
+ "Chart.yaml",
150
+ "kustomization.yaml",
151
+ // CI/CD markers
152
+ ".github/workflows",
153
+ // Blockchain / Web3 markers
154
+ "hardhat.config.js",
155
+ "hardhat.config.ts",
156
+ "foundry.toml",
157
+ // Data engineering markers
158
+ "dbt_project.yml",
159
+ "airflow.cfg",
160
+ // Game engine markers
161
+ "ProjectSettings/ProjectVersion.txt",
162
+ "project.godot",
163
+ // Python framework markers
164
+ "manage.py",
165
+ "requirements.txt",
102
166
  ] as const;
103
167
 
168
+ /** File extensions that indicate SQLite databases in the project. */
169
+ const SQLITE_EXTENSIONS = [".sqlite", ".sqlite3", ".db"] as const;
170
+
171
+ /** File extensions that indicate SQL usage (migrations, schemas, seeds). */
172
+ const SQL_EXTENSIONS = [".sql"] as const;
173
+
174
+ /** File extensions that indicate .NET / C# projects. */
175
+ const DOTNET_EXTENSIONS = [".csproj", ".sln", ".fsproj"] as const;
176
+
177
+ /** File extensions that indicate Vue.js single-file components. */
178
+ const VUE_EXTENSIONS = [".vue"] as const;
179
+
104
180
  const LANGUAGE_MAP: Record<string, string> = {
105
181
  "package.json": "javascript/typescript",
106
182
  "Cargo.toml": "rust",
@@ -111,6 +187,8 @@ const LANGUAGE_MAP: Record<string, string> = {
111
187
  "pom.xml": "java",
112
188
  "build.gradle": "java/kotlin",
113
189
  "build.gradle.kts": "kotlin",
190
+ "app/build.gradle": "java/kotlin",
191
+ "app/build.gradle.kts": "kotlin",
114
192
  "CMakeLists.txt": "c/c++",
115
193
  "composer.json": "php",
116
194
  "pubspec.yaml": "dart/flutter",
@@ -125,6 +203,8 @@ const LANGUAGE_MAP: Record<string, string> = {
125
203
  ".xcodeproj": "swift/xcode",
126
204
  ".xcworkspace": "swift/xcode",
127
205
  "Dockerfile": "docker",
206
+ "manage.py": "python",
207
+ "requirements.txt": "python",
128
208
  };
129
209
 
130
210
  const MONOREPO_MARKERS = [
@@ -159,6 +239,44 @@ const TEST_MARKERS = [
159
239
  "phpunit.xml",
160
240
  ] as const;
161
241
 
242
+ /** Directories skipped during bounded recursive project scans. */
243
+ const RECURSIVE_SCAN_IGNORED_DIRS = new Set([
244
+ ".git",
245
+ "node_modules",
246
+ ".venv",
247
+ "venv",
248
+ "dist",
249
+ "build",
250
+ "coverage",
251
+ ".next",
252
+ ".nuxt",
253
+ "target",
254
+ "vendor",
255
+ ".turbo",
256
+ "Pods",
257
+ "bin",
258
+ "obj",
259
+ ".gradle",
260
+ "DerivedData",
261
+ "out",
262
+ ]) as ReadonlySet<string>;
263
+
264
+ /** Project file markers safe to detect recursively via suffix matching. */
265
+ const ROOT_ONLY_PROJECT_FILES = new Set<string>([
266
+ ".github/workflows",
267
+ "package.json",
268
+ "Gemfile",
269
+ "Makefile",
270
+ "CMakeLists.txt",
271
+ "build.gradle",
272
+ "build.gradle.kts",
273
+ "deno.json",
274
+ "deno.jsonc",
275
+ ]);
276
+
277
+ const MAX_RECURSIVE_SCAN_FILES = 2000;
278
+ const MAX_RECURSIVE_SCAN_DEPTH = 6;
279
+
162
280
  // ─── Core Detection ─────────────────────────────────────────────────────────────
163
281
 
164
282
  /**
@@ -241,8 +359,8 @@ function detectV2Gsd(basePath: string): V2Detection | null {
241
359
  if (!existsSync(gsdPath)) return null;
242
360
 
243
361
  const hasPreferences =
244
- existsSync(join(gsdPath, "preferences.md")) ||
245
- existsSync(join(gsdPath, "PREFERENCES.md"));
362
+ existsSync(join(gsdPath, "PREFERENCES.md")) ||
363
+ existsSync(join(gsdPath, "preferences.md"));
246
364
 
247
365
  const hasContext = existsSync(join(gsdPath, "CONTEXT.md"));
248
366
 
@@ -280,9 +398,88 @@ export function detectProjectSignals(basePath: string): ProjectSignals {
280
398
  }
281
399
  }
282
400
 
401
+ // Bounded recursive scan for nested markers and dependency files.
402
+ // This covers common brownfield layouts like src/App/App.csproj,
403
+ // db/migrations/*.sql, src/components/*.vue, and services/api/pyproject.toml
404
+ // without walking the entire repo or diving into heavyweight folders.
405
+ const scannedFiles = scanProjectFiles(basePath);
406
+
407
+ for (const file of PROJECT_FILES) {
408
+ if (detectedFiles.includes(file) || ROOT_ONLY_PROJECT_FILES.has(file)) continue;
409
+ const hasMatch = file === "requirements.txt"
410
+ ? scannedFiles.some(isPythonRequirementsFile)
411
+ : scannedFiles.some((scannedFile) => matchesProjectFileMarker(scannedFile, file));
412
+ if (hasMatch) {
413
+ pushUnique(detectedFiles, file);
414
+ if (!primaryLanguage && LANGUAGE_MAP[file]) {
415
+ primaryLanguage = LANGUAGE_MAP[file];
416
+ }
417
+ }
418
+ }
419
+
420
+ if (scannedFiles.some((file) => SQLITE_EXTENSIONS.some((ext) => file.endsWith(ext)))) {
421
+ pushUnique(detectedFiles, "*.sqlite");
422
+ }
423
+ if (scannedFiles.some((file) => SQL_EXTENSIONS.some((ext) => file.endsWith(ext)))) {
424
+ pushUnique(detectedFiles, "*.sql");
425
+ }
426
+
427
+ const hasCsproj = scannedFiles.some((file) => file.endsWith(".csproj"));
428
+ const hasFsproj = scannedFiles.some((file) => file.endsWith(".fsproj"));
429
+ const hasSln = scannedFiles.some((file) => file.endsWith(".sln"));
430
+
431
+ if (hasCsproj) {
432
+ pushUnique(detectedFiles, "*.csproj");
433
+ if (!primaryLanguage) primaryLanguage = "csharp";
434
+ }
435
+ if (hasFsproj) {
436
+ pushUnique(detectedFiles, "*.fsproj");
437
+ if (!primaryLanguage) primaryLanguage = "fsharp";
438
+ }
439
+ if (hasSln) {
440
+ pushUnique(detectedFiles, "*.sln");
441
+ if (!primaryLanguage) primaryLanguage = "dotnet";
442
+ }
443
+
444
+ if (scannedFiles.some((file) => VUE_EXTENSIONS.some((ext) => file.endsWith(ext)))) {
445
+ pushUnique(detectedFiles, "*.vue");
446
+ }
447
+
448
+ // Python framework detection — scan dependency files for framework-specific packages.
449
+ // Adds synthetic markers (e.g. "dep:fastapi") so skill catalog matchFiles can reference them.
450
+ const dependencyFiles = scannedFiles.filter((file) =>
451
+ isPythonRequirementsFile(file) || file.endsWith("pyproject.toml"),
452
+ );
453
+ if (containsFastapiDependency(basePath, dependencyFiles)) {
454
+ pushUnique(detectedFiles, "dep:fastapi");
455
+ }
456
+
457
+ const springBootBuildFiles = scannedFiles.filter((file) =>
458
+ file.endsWith("pom.xml") || file.endsWith("build.gradle") || file.endsWith("build.gradle.kts"),
459
+ );
460
+ const springBootVersionCatalogs = scannedFiles.filter((file) => file.endsWith(".versions.toml"));
461
+ const springBootSettingsFiles = scannedFiles.filter((file) =>
462
+ file.endsWith("settings.gradle") || file.endsWith("settings.gradle.kts"),
463
+ );
464
+ if (containsSpringBootMarker(basePath, springBootBuildFiles, springBootVersionCatalogs, springBootSettingsFiles)) {
465
+ pushUnique(detectedFiles, "dep:spring-boot");
466
+ if (!primaryLanguage) {
467
+ primaryLanguage = "java/kotlin";
468
+ }
469
+ }
470
+
283
471
  // Git repo detection
284
472
  const isGitRepo = existsSync(join(basePath, ".git"));
285
473
 
474
+ // Xcode platform detection — parse SDKROOT from project.pbxproj
475
+ const xcodePlatforms = detectXcodePlatforms(basePath);
476
+
477
+ // Set primaryLanguage to swift when an Xcode project is found but no
478
+ // Package.swift was detected (CocoaPods or SPM-less projects).
479
+ if (!primaryLanguage && xcodePlatforms.length > 0) {
480
+ primaryLanguage = "swift";
481
+ }
482
+
286
483
  // Monorepo detection
287
484
  let isMonorepo = false;
288
485
  for (const marker of MONOREPO_MARKERS) {
@@ -325,6 +522,7 @@ export function detectProjectSignals(basePath: string): ProjectSignals {
325
522
  isGitRepo,
326
523
  isMonorepo,
327
524
  primaryLanguage,
525
+ xcodePlatforms,
328
526
  hasCI,
329
527
  hasTests,
330
528
  packageManager,
@@ -332,6 +530,100 @@ export function detectProjectSignals(basePath: string): ProjectSignals {
332
530
  };
333
531
  }
334
532
 
533
+ // ─── Xcode Platform Detection ───────────────────────────────────────────────────
534
+
535
+ /** Known SDKROOT values → canonical platform names. */
536
+ const SDKROOT_MAP: Record<string, XcodePlatform> = {
537
+ iphoneos: "iphoneos",
538
+ iphonesimulator: "iphoneos", // simulator builds still target iOS
539
+ macosx: "macosx",
540
+ watchos: "watchos",
541
+ watchsimulator: "watchos",
542
+ appletvos: "appletvos",
543
+ appletvsimulator: "appletvos",
544
+ xros: "xros",
545
+ xrsimulator: "xros",
546
+ };
547
+
548
+ /** Regex for SUPPORTED_PLATFORMS — fallback when SDKROOT = auto (Xcode 15+). */
549
+ const SUPPORTED_PLATFORMS_RE = /SUPPORTED_PLATFORMS\s*=\s*"([^"]+)"/gi;
550
+
551
+ /** Read at most `maxBytes` from a file without loading the full file into memory. */
552
+ function readBounded(filePath: string, maxBytes: number): string {
553
+ const buf = Buffer.alloc(maxBytes);
554
+ const fd = openSync(filePath, "r");
555
+ try {
556
+ const bytesRead = readSync(fd, buf, 0, maxBytes, 0);
557
+ return buf.toString("utf-8", 0, bytesRead);
558
+ } finally {
559
+ closeSync(fd);
560
+ }
561
+ }
562
+
563
+ /** Common subdirectories where .xcodeproj may live in monorepos / standard layouts. */
564
+ const XCODE_SUBDIRS = ["ios", "macos", "app", "apps"] as const;
565
+
566
+ /**
567
+ * Scan *.xcodeproj directories for project.pbxproj and extract SDKROOT values.
568
+ * Returns deduplicated, canonical platform list (e.g. ["iphoneos"]).
569
+ *
570
+ * Reading the pbxproj is a lightweight regex scan — no full plist parsing needed.
571
+ * We read at most 1 MB per file to keep detection fast.
572
+ * Searches both the project root and common subdirectories (ios/, macos/, app/).
573
+ */
574
+ function detectXcodePlatforms(basePath: string): XcodePlatform[] {
575
+ const platforms = new Set<XcodePlatform>();
576
+
577
+ // Directories to scan: project root + common subdirs
578
+ const dirsToScan = [basePath];
579
+ for (const sub of XCODE_SUBDIRS) {
580
+ const subPath = join(basePath, sub);
581
+ if (existsSync(subPath)) dirsToScan.push(subPath);
582
+ }
583
+
584
+ for (const dir of dirsToScan) {
585
+ try {
586
+ const entries = readdirSync(dir, { withFileTypes: true });
587
+ for (const entry of entries) {
588
+ if (!entry.isDirectory() || !entry.name.endsWith(".xcodeproj")) continue;
589
+ const pbxprojPath = join(dir, entry.name, "project.pbxproj");
590
+ try {
591
+ const content = readBounded(pbxprojPath, 1024 * 1024);
592
+ // Match SDKROOT = <value>; — both quoted and unquoted forms
593
+ const sdkRe = /SDKROOT\s*=\s*"?([a-z]+)"?\s*;/gi;
594
+ let m: RegExpExecArray | null;
595
+ let foundExplicit = false;
596
+ while ((m = sdkRe.exec(content)) !== null) {
597
+ const val = m[1].toLowerCase();
598
+ if (val === "auto") continue; // handled below via SUPPORTED_PLATFORMS
599
+ const canonical = SDKROOT_MAP[val];
600
+ if (canonical) {
601
+ platforms.add(canonical);
602
+ foundExplicit = true;
603
+ }
604
+ }
605
+ // Xcode 15+ defaults SDKROOT to "auto"; fall back to SUPPORTED_PLATFORMS
606
+ if (!foundExplicit) {
607
+ let sp: RegExpExecArray | null;
608
+ while ((sp = SUPPORTED_PLATFORMS_RE.exec(content)) !== null) {
609
+ for (const tok of sp[1].split(/\s+/)) {
610
+ const canonical = SDKROOT_MAP[tok.toLowerCase()];
611
+ if (canonical) platforms.add(canonical);
612
+ }
613
+ }
614
+ SUPPORTED_PLATFORMS_RE.lastIndex = 0;
615
+ }
616
+ } catch {
617
+ // unreadable pbxproj — skip
618
+ }
619
+ }
620
+ } catch {
621
+ // unreadable directory
622
+ }
623
+ }
624
+ return [...platforms];
625
+ }
626
+
335
627
  // ─── Package Manager Detection ──────────────────────────────────────────────────
336
628
 
337
629
  function detectPackageManager(basePath: string): string | undefined {
@@ -392,7 +684,7 @@ function detectVerificationCommands(
392
684
  commands.push("go vet ./...");
393
685
  }
394
686
 
395
- if (detectedFiles.includes("pyproject.toml") || detectedFiles.includes("setup.py")) {
687
+ if (detectedFiles.includes("pyproject.toml") || detectedFiles.includes("setup.py") || detectedFiles.includes("requirements.txt")) {
396
688
  commands.push("pytest");
397
689
  }
398
690
 
@@ -422,8 +714,8 @@ function detectVerificationCommands(
422
714
  */
423
715
  export function hasGlobalSetup(): boolean {
424
716
  return (
425
- existsSync(join(gsdHome, "preferences.md")) ||
426
- existsSync(join(gsdHome, "PREFERENCES.md"))
717
+ existsSync(join(gsdHome, "PREFERENCES.md")) ||
718
+ existsSync(join(gsdHome, "preferences.md"))
427
719
  );
428
720
  }
429
721
 
@@ -436,8 +728,8 @@ export function isFirstEverLaunch(): boolean {
436
728
 
437
729
  // If we have preferences, not first launch
438
730
  if (
439
- existsSync(join(gsdHome, "preferences.md")) ||
440
- existsSync(join(gsdHome, "PREFERENCES.md"))
731
+ existsSync(join(gsdHome, "PREFERENCES.md")) ||
732
+ existsSync(join(gsdHome, "preferences.md"))
441
733
  ) {
442
734
  return false;
443
735
  }
@@ -487,3 +779,370 @@ function readMakefileTargets(basePath: string): string[] {
487
779
  return [];
488
780
  }
489
781
  }
782
+
783
+ function pushUnique(arr: string[], value: string): void {
784
+ if (!arr.includes(value)) arr.push(value);
785
+ }
786
+
787
+ function matchesProjectFileMarker(scannedFile: string, marker: string): boolean {
788
+ const normalized = scannedFile.replaceAll("\\", "/");
789
+ return (
790
+ normalized === marker ||
791
+ normalized.endsWith(`/${marker}`)
792
+ );
793
+ }
794
+
795
+ function isPythonRequirementsFile(relativePath: string): boolean {
796
+ const normalized = relativePath.replaceAll("\\", "/");
797
+ const basename = normalized.slice(normalized.lastIndexOf("/") + 1);
798
+ return (
799
+ basename === "requirements.txt" ||
800
+ basename === "requirements.in" ||
801
+ /^requirements([-.].+)?\.(txt|in)$/i.test(basename) ||
802
+ /(^|\/)requirements\/.+\.(txt|in)$/i.test(normalized)
803
+ );
804
+ }
805
+
806
+ function containsFastapiDependency(basePath: string, relativePaths: string[]): boolean {
807
+ for (const relativePath of relativePaths) {
808
+ try {
809
+ const raw = readBounded(join(basePath, relativePath), 64 * 1024);
810
+ const content = extractDependencyContent(relativePath, raw);
811
+ if (isPythonRequirementsFile(relativePath)) {
812
+ for (const line of content.split("\n")) {
813
+ if (extractRequirementName(line) === "fastapi") return true;
814
+ }
815
+ continue;
816
+ }
817
+
818
+ if (relativePath.endsWith("pyproject.toml")) {
819
+ if (containsFastapiInPyproject(content)) return true;
820
+ }
821
+ } catch {
822
+ // unreadable file — continue scanning other candidate files
823
+ }
824
+ }
825
+
826
+ return false;
827
+ }
828
+
829
+ function containsSpringBootMarker(
830
+ basePath: string,
831
+ buildFiles: string[],
832
+ versionCatalogFiles: string[],
833
+ settingsFiles: string[],
834
+ ): boolean {
835
+ const usedPluginAliases = new Set<string>();
836
+ const usedLibraryAliases = new Set<string>();
837
+ const catalogAccessors = resolveVersionCatalogAccessors(basePath, versionCatalogFiles, settingsFiles);
838
+
839
+ for (const relativePath of buildFiles) {
840
+ try {
841
+ const raw = readBounded(join(basePath, relativePath), 64 * 1024);
842
+ const content = stripDependencyComments(relativePath, raw);
843
+ if (containsDirectSpringBootReference(relativePath, content)) {
844
+ return true;
845
+ }
846
+
847
+ const normalized = content.toLowerCase();
848
+ let match: RegExpExecArray | null;
849
+ for (const accessor of catalogAccessors) {
850
+ const aliasRe = new RegExp(`alias\\(\\s*${accessor}\\.plugins\\.([a-z0-9_.-]+)\\s*\\)`, "gi");
851
+ while ((match = aliasRe.exec(normalized)) !== null) {
852
+ usedPluginAliases.add(normalizePluginAlias(match[1]));
853
+ }
854
+
855
+ const libraryAliasRe = new RegExp(`\\b${accessor}\\.((?!plugins\\b)[a-z0-9_.-]+)`, "gi");
856
+ while ((match = libraryAliasRe.exec(normalized)) !== null) {
857
+ usedLibraryAliases.add(normalizePluginAlias(match[1]));
858
+ }
859
+ }
860
+ } catch {
861
+ // unreadable build file — continue scanning others
862
+ }
863
+ }
864
+
865
+ if (usedPluginAliases.size === 0 && usedLibraryAliases.size === 0) {
866
+ return false;
867
+ }
868
+ if (versionCatalogFiles.length === 0) {
869
+ return false;
870
+ }
871
+
872
+ const springBootAliases = new Set<string>();
873
+ const springBootLibraries = new Set<string>();
874
+ const pendingSpringBootBundles: Array<{ bundleAlias: string; referencedAliases: string[] }> = [];
875
+ for (const relativePath of versionCatalogFiles) {
876
+ try {
877
+ const raw = readBounded(join(basePath, relativePath), 64 * 1024);
878
+ const content = stripDependencyComments(relativePath, raw);
879
+ const aliasRe = /^\s*([A-Za-z0-9_.-]+)\s*=\s*\{[^\n}]*\bid\s*=\s*["']org\.springframework\.boot["'][^\n}]*\}/gm;
880
+ let match: RegExpExecArray | null;
881
+ while ((match = aliasRe.exec(content)) !== null) {
882
+ springBootAliases.add(normalizePluginAlias(match[1]));
883
+ }
884
+
885
+ const libraryRe = /^\s*([A-Za-z0-9_.-]+)\s*=\s*\{[^\n}]*\b(module\s*=\s*["']org\.springframework\.boot:[^"']+["']|group\s*=\s*["']org\.springframework\.boot["'][^\n}]*\bname\s*=\s*["']spring-boot[^"']*["'])[^\n}]*\}/gm;
886
+ while ((match = libraryRe.exec(content)) !== null) {
887
+ springBootLibraries.add(normalizePluginAlias(match[1]));
888
+ }
889
+
890
+ const bundleRe = /^\s*([A-Za-z0-9_.-]+)\s*=\s*\[([\s\S]*?)\]/gm;
891
+ while ((match = bundleRe.exec(content)) !== null) {
892
+ pendingSpringBootBundles.push({
893
+ bundleAlias: normalizePluginAlias(`bundles.${match[1]}`),
894
+ referencedAliases: match[2]
895
+ .split(",")
896
+ .map((part) => normalizePluginAlias(part.replace(/["'\s]/g, "")))
897
+ .filter(Boolean),
898
+ });
899
+ }
900
+ } catch {
901
+ // unreadable version catalog — continue scanning others
902
+ }
903
+ }
904
+
905
+ const springBootBundles = new Set<string>();
906
+ for (const pendingBundle of pendingSpringBootBundles) {
907
+ if (pendingBundle.referencedAliases.some((alias) => springBootLibraries.has(alias))) {
908
+ springBootBundles.add(pendingBundle.bundleAlias);
909
+ }
910
+ }
911
+
912
+ for (const alias of usedPluginAliases) {
913
+ if (springBootAliases.has(alias)) return true;
914
+ }
915
+ for (const alias of usedLibraryAliases) {
916
+ if (springBootLibraries.has(alias) || springBootBundles.has(alias)) return true;
917
+ }
918
+
919
+ return false;
920
+ }
921
+
922
+ function stripDependencyComments(relativePath: string, content: string): string {
923
+ if (relativePath.endsWith("requirements.txt")) {
924
+ return content.replace(/(^|\s)#.*$/gm, "");
925
+ }
926
+ if (relativePath.endsWith("pyproject.toml")) {
927
+ return content.replace(/(^|\s)#.*$/gm, "");
928
+ }
929
+ if (relativePath.endsWith(".versions.toml")) {
930
+ return content.replace(/(^|\s)#.*$/gm, "");
931
+ }
932
+ if (relativePath.endsWith("settings.gradle") || relativePath.endsWith("settings.gradle.kts")) {
933
+ return content
934
+ .replace(/\/\*[\s\S]*?\*\//g, "")
935
+ .replace(/\/\/.*$/gm, "");
936
+ }
937
+ if (relativePath.endsWith("pom.xml")) {
938
+ return content.replace(/<!--[\s\S]*?-->/g, "");
939
+ }
940
+ if (relativePath.endsWith("build.gradle") || relativePath.endsWith("build.gradle.kts")) {
941
+ return content
942
+ .replace(/\/\*[\s\S]*?\*\//g, "")
943
+ .replace(/\/\/.*$/gm, "");
944
+ }
945
+ return content;
946
+ }
947
+
948
+ function extractDependencyContent(relativePath: string, content: string): string {
949
+ const stripped = stripDependencyComments(relativePath, content);
950
+ if (relativePath.endsWith("pyproject.toml")) {
951
+ return extractPyprojectDependencySections(stripped);
952
+ }
953
+ return stripped;
954
+ }
955
+
956
+ function extractRequirementName(spec: string): string | null {
957
+ const trimmed = spec.trim().replace(/^["']|["']$/g, "");
958
+ if (!trimmed) return null;
959
+
960
+ const match = trimmed.match(/^([A-Za-z0-9_.-]+)(?:\[[^\]]+\])?(?=\s*(?:@|[<>=!~;]|$))/);
961
+ if (!match) return null;
962
+ return normalizePackageName(match[1]);
963
+ }
964
+
965
+ function containsFastapiInPyproject(content: string): boolean {
966
+ for (const line of content.split("\n")) {
967
+ const keyMatch = line.match(/^\s*([A-Za-z0-9_.-]+)\s*=/);
968
+ if (keyMatch) {
969
+ const key = normalizePackageName(keyMatch[1]);
970
+ if (key === "fastapi") {
971
+ return true;
972
+ }
973
+ if (key !== "dependencies") {
974
+ continue;
975
+ }
976
+ }
977
+
978
+ const quotedSpecRe = /["']([^"']+)["']/g;
979
+ let match: RegExpExecArray | null;
980
+ while ((match = quotedSpecRe.exec(line)) !== null) {
981
+ if (extractRequirementName(match[1]) === "fastapi") {
982
+ return true;
983
+ }
984
+ }
985
+ }
986
+
987
+ return false;
988
+ }
989
+
990
+ function containsDirectSpringBootReference(relativePath: string, content: string): boolean {
991
+ if (relativePath.endsWith("pom.xml")) {
992
+ return /<groupId>\s*org\.springframework\.boot\s*<\/groupId>/i.test(content);
993
+ }
994
+
995
+ if (relativePath.endsWith("build.gradle") || relativePath.endsWith("build.gradle.kts")) {
996
+ return /(id\s*\(?\s*["']org\.springframework\.boot["']|apply\s*\(?\s*plugin\s*[:=]\s*["']org\.springframework\.boot["']|(?:implementation|api|compileOnly|runtimeOnly|testImplementation|annotationProcessor|kapt)\s*\(?\s*["'][^"']*org\.springframework\.boot:[^"']*spring-boot[^"']*["'])/i.test(content);
997
+ }
998
+
999
+ return false;
1000
+ }
1001
+
1002
+ function extractPyprojectDependencySections(content: string): string {
1003
+ const lines = content.split("\n");
1004
+ const collected: string[] = [];
1005
+ let section = "";
1006
+ let collectingProjectDeps = false;
1007
+ let collectingOptionalDeps = false;
1008
+ let bracketDepth = 0;
1009
+
1010
+ for (const line of lines) {
1011
+ const trimmed = line.trim();
1012
+
1013
+ if (collectingProjectDeps) {
1014
+ collected.push(line);
1015
+ bracketDepth += countChar(line, "[") - countChar(line, "]");
1016
+ if (bracketDepth <= 0) {
1017
+ collectingProjectDeps = false;
1018
+ }
1019
+ continue;
1020
+ }
1021
+
1022
+ if (collectingOptionalDeps) {
1023
+ collected.push(line);
1024
+ bracketDepth += countChar(line, "[") - countChar(line, "]");
1025
+ if (bracketDepth <= 0) {
1026
+ collectingOptionalDeps = false;
1027
+ }
1028
+ continue;
1029
+ }
1030
+
1031
+ const sectionMatch = trimmed.match(/^\[([^\]]+)\]$/);
1032
+ if (sectionMatch) {
1033
+ section = sectionMatch[1].trim();
1034
+ continue;
1035
+ }
1036
+
1037
+ if (section === "project" && /^dependencies\s*=\s*\[/.test(trimmed)) {
1038
+ collected.push(line);
1039
+ bracketDepth = countChar(line, "[") - countChar(line, "]");
1040
+ collectingProjectDeps = bracketDepth > 0;
1041
+ continue;
1042
+ }
1043
+
1044
+ if (
1045
+ section === "project.optional-dependencies" ||
1046
+ section === "tool.poetry.dependencies"
1047
+ ) {
1048
+ if (section === "project.optional-dependencies") {
1049
+ const equalsIndex = line.indexOf("=");
1050
+ if (equalsIndex !== -1) {
1051
+ const value = line.slice(equalsIndex + 1);
1052
+ collected.push(value);
1053
+ bracketDepth = countChar(value, "[") - countChar(value, "]");
1054
+ collectingOptionalDeps = bracketDepth > 0;
1055
+ }
1056
+ } else {
1057
+ collected.push(line);
1058
+ }
1059
+ }
1060
+ }
1061
+
1062
+ return collected.join("\n");
1063
+ }
1064
+
1065
+ function countChar(text: string, char: string): number {
1066
+ return [...text].filter((c) => c === char).length;
1067
+ }
1068
+
1069
+ function normalizePackageName(name: string): string {
1070
+ return name.toLowerCase().replace(/[_.]/g, "-");
1071
+ }
1072
+
1073
+ function normalizePluginAlias(alias: string): string {
1074
+ return alias.toLowerCase().replace(/[-_]/g, ".");
1075
+ }
1076
+
1077
+ function versionCatalogAccessorName(relativePath: string): string {
1078
+ const normalized = relativePath.replaceAll("\\", "/");
1079
+ const basename = normalized.slice(normalized.lastIndexOf("/") + 1);
1080
+ return basename.replace(/\.versions\.toml$/i, "").toLowerCase();
1081
+ }
1082
+
1083
+ function resolveVersionCatalogAccessors(
1084
+ basePath: string,
1085
+ versionCatalogFiles: string[],
1086
+ settingsFiles: string[],
1087
+ ): Set<string> {
1088
+ const accessors = new Set(versionCatalogFiles.map(versionCatalogAccessorName).filter(Boolean));
1089
+ if (versionCatalogFiles.length === 0 || settingsFiles.length === 0) {
1090
+ return accessors;
1091
+ }
1092
+
1093
+ for (const settingsFile of settingsFiles) {
1094
+ try {
1095
+ const raw = readBounded(join(basePath, settingsFile), 64 * 1024);
1096
+ const content = stripDependencyComments(settingsFile, raw);
1097
+ const createRe = /create\(\s*["']([A-Za-z0-9_]+)["']\s*\)\s*\{[\s\S]*?([A-Za-z0-9_.-]+\.versions\.toml)["']?\s*\)\s*\)/g;
1098
+ let match: RegExpExecArray | null;
1099
+ while ((match = createRe.exec(content)) !== null) {
1100
+ const accessor = match[1].toLowerCase();
1101
+ const catalogBasename = match[2].replaceAll("\\", "/").split("/").pop()!;
1102
+ if (versionCatalogFiles.some((file) => {
1103
+ const normalized = file.replaceAll("\\", "/");
1104
+ return normalized === catalogBasename || normalized.endsWith(`/${catalogBasename}`);
1105
+ })) {
1106
+ accessors.add(accessor);
1107
+ }
1108
+ }
1109
+ } catch {
1110
+ // unreadable settings file — ignore
1111
+ }
1112
+ }
1113
+
1114
+ return accessors;
1115
+ }
1116
+
1117
+ function scanProjectFiles(basePath: string): string[] {
1118
+ const files: string[] = [];
1119
+ const queue: Array<{ path: string; depth: number }> = [{ path: basePath, depth: 0 }];
1120
+
1121
+ while (queue.length > 0 && files.length < MAX_RECURSIVE_SCAN_FILES) {
1122
+ const current = queue.shift()!;
1123
+ let entries: Array<{ name: string; isDirectory(): boolean; isFile(): boolean }>;
1124
+ try {
1125
+ entries = readdirSync(current.path, { withFileTypes: true, encoding: "utf8" });
1126
+ } catch {
1127
+ continue;
1128
+ }
1129
+
1130
+ for (const entry of entries) {
1131
+ const entryPath = join(current.path, entry.name);
1132
+ const relativePath = entryPath.slice(basePath.length + 1);
1133
+
1134
+ if (entry.isDirectory()) {
1135
+ if (current.depth < MAX_RECURSIVE_SCAN_DEPTH && !RECURSIVE_SCAN_IGNORED_DIRS.has(entry.name)) {
1136
+ queue.push({ path: entryPath, depth: current.depth + 1 });
1137
+ }
1138
+ continue;
1139
+ }
1140
+
1141
+ if (!entry.isFile()) continue;
1142
+ files.push(relativePath);
1143
+ if (files.length >= MAX_RECURSIVE_SCAN_FILES) break;
1144
+ }
1145
+ }
1146
+
1147
+ return files;
1148
+ }