@selvakumaresra/specship 0.1.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 (624) hide show
  1. package/.claude-plugin/plugin.json +6 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/agents/specship-explorer.md +29 -0
  5. package/commands/cg-drifted.md +23 -0
  6. package/commands/cg-explore.md +13 -0
  7. package/commands/cg-fix.md +21 -0
  8. package/commands/cg-impact.md +13 -0
  9. package/commands/cg-implement.md +23 -0
  10. package/commands/cg-relink.md +21 -0
  11. package/commands/cg-spec.md +19 -0
  12. package/commands/cg-sync.md +8 -0
  13. package/commands/cg-trace.md +13 -0
  14. package/dist/bin/node-version-check.d.ts +37 -0
  15. package/dist/bin/node-version-check.d.ts.map +1 -0
  16. package/dist/bin/node-version-check.js +79 -0
  17. package/dist/bin/node-version-check.js.map +1 -0
  18. package/dist/bin/specship.d.ts +25 -0
  19. package/dist/bin/specship.d.ts.map +1 -0
  20. package/dist/bin/specship.js +2018 -0
  21. package/dist/bin/specship.js.map +1 -0
  22. package/dist/bin/uninstall.d.ts +13 -0
  23. package/dist/bin/uninstall.d.ts.map +1 -0
  24. package/dist/bin/uninstall.js +35 -0
  25. package/dist/bin/uninstall.js.map +1 -0
  26. package/dist/context/formatter.d.ts +30 -0
  27. package/dist/context/formatter.d.ts.map +1 -0
  28. package/dist/context/formatter.js +263 -0
  29. package/dist/context/formatter.js.map +1 -0
  30. package/dist/context/index.d.ts +119 -0
  31. package/dist/context/index.d.ts.map +1 -0
  32. package/dist/context/index.js +1289 -0
  33. package/dist/context/index.js.map +1 -0
  34. package/dist/context/markers.d.ts +19 -0
  35. package/dist/context/markers.d.ts.map +1 -0
  36. package/dist/context/markers.js +22 -0
  37. package/dist/context/markers.js.map +1 -0
  38. package/dist/db/index.d.ts +101 -0
  39. package/dist/db/index.d.ts.map +1 -0
  40. package/dist/db/index.js +276 -0
  41. package/dist/db/index.js.map +1 -0
  42. package/dist/db/migrations.d.ts +44 -0
  43. package/dist/db/migrations.d.ts.map +1 -0
  44. package/dist/db/migrations.js +427 -0
  45. package/dist/db/migrations.js.map +1 -0
  46. package/dist/db/queries.d.ts +357 -0
  47. package/dist/db/queries.d.ts.map +1 -0
  48. package/dist/db/queries.js +1504 -0
  49. package/dist/db/queries.js.map +1 -0
  50. package/dist/db/schema.sql +410 -0
  51. package/dist/db/spec-queries.d.ts +101 -0
  52. package/dist/db/spec-queries.d.ts.map +1 -0
  53. package/dist/db/spec-queries.js +675 -0
  54. package/dist/db/spec-queries.js.map +1 -0
  55. package/dist/db/sqlite-adapter.d.ts +65 -0
  56. package/dist/db/sqlite-adapter.d.ts.map +1 -0
  57. package/dist/db/sqlite-adapter.js +214 -0
  58. package/dist/db/sqlite-adapter.js.map +1 -0
  59. package/dist/directory.d.ts +57 -0
  60. package/dist/directory.d.ts.map +1 -0
  61. package/dist/directory.js +253 -0
  62. package/dist/directory.js.map +1 -0
  63. package/dist/errors.d.ts +136 -0
  64. package/dist/errors.d.ts.map +1 -0
  65. package/dist/errors.js +219 -0
  66. package/dist/errors.js.map +1 -0
  67. package/dist/extraction/dfm-extractor.d.ts +31 -0
  68. package/dist/extraction/dfm-extractor.d.ts.map +1 -0
  69. package/dist/extraction/dfm-extractor.js +151 -0
  70. package/dist/extraction/dfm-extractor.js.map +1 -0
  71. package/dist/extraction/generated-detection.d.ts +30 -0
  72. package/dist/extraction/generated-detection.d.ts.map +1 -0
  73. package/dist/extraction/generated-detection.js +80 -0
  74. package/dist/extraction/generated-detection.js.map +1 -0
  75. package/dist/extraction/grammars.d.ts +100 -0
  76. package/dist/extraction/grammars.d.ts.map +1 -0
  77. package/dist/extraction/grammars.js +426 -0
  78. package/dist/extraction/grammars.js.map +1 -0
  79. package/dist/extraction/index.d.ts +138 -0
  80. package/dist/extraction/index.d.ts.map +1 -0
  81. package/dist/extraction/index.js +1394 -0
  82. package/dist/extraction/index.js.map +1 -0
  83. package/dist/extraction/languages/c-cpp.d.ts +4 -0
  84. package/dist/extraction/languages/c-cpp.d.ts.map +1 -0
  85. package/dist/extraction/languages/c-cpp.js +171 -0
  86. package/dist/extraction/languages/c-cpp.js.map +1 -0
  87. package/dist/extraction/languages/csharp.d.ts +3 -0
  88. package/dist/extraction/languages/csharp.d.ts.map +1 -0
  89. package/dist/extraction/languages/csharp.js +73 -0
  90. package/dist/extraction/languages/csharp.js.map +1 -0
  91. package/dist/extraction/languages/dart.d.ts +3 -0
  92. package/dist/extraction/languages/dart.d.ts.map +1 -0
  93. package/dist/extraction/languages/dart.js +192 -0
  94. package/dist/extraction/languages/dart.js.map +1 -0
  95. package/dist/extraction/languages/go.d.ts +3 -0
  96. package/dist/extraction/languages/go.d.ts.map +1 -0
  97. package/dist/extraction/languages/go.js +74 -0
  98. package/dist/extraction/languages/go.js.map +1 -0
  99. package/dist/extraction/languages/index.d.ts +10 -0
  100. package/dist/extraction/languages/index.d.ts.map +1 -0
  101. package/dist/extraction/languages/index.js +51 -0
  102. package/dist/extraction/languages/index.js.map +1 -0
  103. package/dist/extraction/languages/java.d.ts +3 -0
  104. package/dist/extraction/languages/java.d.ts.map +1 -0
  105. package/dist/extraction/languages/java.js +70 -0
  106. package/dist/extraction/languages/java.js.map +1 -0
  107. package/dist/extraction/languages/javascript.d.ts +3 -0
  108. package/dist/extraction/languages/javascript.d.ts.map +1 -0
  109. package/dist/extraction/languages/javascript.js +90 -0
  110. package/dist/extraction/languages/javascript.js.map +1 -0
  111. package/dist/extraction/languages/kotlin.d.ts +3 -0
  112. package/dist/extraction/languages/kotlin.d.ts.map +1 -0
  113. package/dist/extraction/languages/kotlin.js +259 -0
  114. package/dist/extraction/languages/kotlin.js.map +1 -0
  115. package/dist/extraction/languages/lua.d.ts +3 -0
  116. package/dist/extraction/languages/lua.d.ts.map +1 -0
  117. package/dist/extraction/languages/lua.js +150 -0
  118. package/dist/extraction/languages/lua.js.map +1 -0
  119. package/dist/extraction/languages/luau.d.ts +3 -0
  120. package/dist/extraction/languages/luau.d.ts.map +1 -0
  121. package/dist/extraction/languages/luau.js +37 -0
  122. package/dist/extraction/languages/luau.js.map +1 -0
  123. package/dist/extraction/languages/objc.d.ts +3 -0
  124. package/dist/extraction/languages/objc.d.ts.map +1 -0
  125. package/dist/extraction/languages/objc.js +133 -0
  126. package/dist/extraction/languages/objc.js.map +1 -0
  127. package/dist/extraction/languages/pascal.d.ts +3 -0
  128. package/dist/extraction/languages/pascal.d.ts.map +1 -0
  129. package/dist/extraction/languages/pascal.js +66 -0
  130. package/dist/extraction/languages/pascal.js.map +1 -0
  131. package/dist/extraction/languages/php.d.ts +3 -0
  132. package/dist/extraction/languages/php.d.ts.map +1 -0
  133. package/dist/extraction/languages/php.js +107 -0
  134. package/dist/extraction/languages/php.js.map +1 -0
  135. package/dist/extraction/languages/python.d.ts +3 -0
  136. package/dist/extraction/languages/python.d.ts.map +1 -0
  137. package/dist/extraction/languages/python.js +56 -0
  138. package/dist/extraction/languages/python.js.map +1 -0
  139. package/dist/extraction/languages/ruby.d.ts +3 -0
  140. package/dist/extraction/languages/ruby.d.ts.map +1 -0
  141. package/dist/extraction/languages/ruby.js +114 -0
  142. package/dist/extraction/languages/ruby.js.map +1 -0
  143. package/dist/extraction/languages/rust.d.ts +3 -0
  144. package/dist/extraction/languages/rust.d.ts.map +1 -0
  145. package/dist/extraction/languages/rust.js +109 -0
  146. package/dist/extraction/languages/rust.js.map +1 -0
  147. package/dist/extraction/languages/scala.d.ts +3 -0
  148. package/dist/extraction/languages/scala.d.ts.map +1 -0
  149. package/dist/extraction/languages/scala.js +139 -0
  150. package/dist/extraction/languages/scala.js.map +1 -0
  151. package/dist/extraction/languages/swift.d.ts +3 -0
  152. package/dist/extraction/languages/swift.d.ts.map +1 -0
  153. package/dist/extraction/languages/swift.js +91 -0
  154. package/dist/extraction/languages/swift.js.map +1 -0
  155. package/dist/extraction/languages/typescript.d.ts +3 -0
  156. package/dist/extraction/languages/typescript.d.ts.map +1 -0
  157. package/dist/extraction/languages/typescript.js +129 -0
  158. package/dist/extraction/languages/typescript.js.map +1 -0
  159. package/dist/extraction/liquid-extractor.d.ts +52 -0
  160. package/dist/extraction/liquid-extractor.d.ts.map +1 -0
  161. package/dist/extraction/liquid-extractor.js +313 -0
  162. package/dist/extraction/liquid-extractor.js.map +1 -0
  163. package/dist/extraction/mybatis-extractor.d.ts +48 -0
  164. package/dist/extraction/mybatis-extractor.d.ts.map +1 -0
  165. package/dist/extraction/mybatis-extractor.js +198 -0
  166. package/dist/extraction/mybatis-extractor.js.map +1 -0
  167. package/dist/extraction/parse-worker.d.ts +8 -0
  168. package/dist/extraction/parse-worker.d.ts.map +1 -0
  169. package/dist/extraction/parse-worker.js +94 -0
  170. package/dist/extraction/parse-worker.js.map +1 -0
  171. package/dist/extraction/specs/markdown-spec-extractor.d.ts +59 -0
  172. package/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -0
  173. package/dist/extraction/specs/markdown-spec-extractor.js +327 -0
  174. package/dist/extraction/specs/markdown-spec-extractor.js.map +1 -0
  175. package/dist/extraction/specs/types.d.ts +39 -0
  176. package/dist/extraction/specs/types.d.ts.map +1 -0
  177. package/dist/extraction/specs/types.js +8 -0
  178. package/dist/extraction/specs/types.js.map +1 -0
  179. package/dist/extraction/svelte-extractor.d.ts +56 -0
  180. package/dist/extraction/svelte-extractor.d.ts.map +1 -0
  181. package/dist/extraction/svelte-extractor.js +272 -0
  182. package/dist/extraction/svelte-extractor.js.map +1 -0
  183. package/dist/extraction/tree-sitter-helpers.d.ts +28 -0
  184. package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -0
  185. package/dist/extraction/tree-sitter-helpers.js +103 -0
  186. package/dist/extraction/tree-sitter-helpers.js.map +1 -0
  187. package/dist/extraction/tree-sitter-types.d.ts +193 -0
  188. package/dist/extraction/tree-sitter-types.d.ts.map +1 -0
  189. package/dist/extraction/tree-sitter-types.js +10 -0
  190. package/dist/extraction/tree-sitter-types.js.map +1 -0
  191. package/dist/extraction/tree-sitter.d.ts +317 -0
  192. package/dist/extraction/tree-sitter.d.ts.map +1 -0
  193. package/dist/extraction/tree-sitter.js +3092 -0
  194. package/dist/extraction/tree-sitter.js.map +1 -0
  195. package/dist/extraction/vue-extractor.d.ts +51 -0
  196. package/dist/extraction/vue-extractor.d.ts.map +1 -0
  197. package/dist/extraction/vue-extractor.js +251 -0
  198. package/dist/extraction/vue-extractor.js.map +1 -0
  199. package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
  200. package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
  201. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  202. package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
  203. package/dist/extraction/wasm-runtime-flags.d.ts +38 -0
  204. package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -0
  205. package/dist/extraction/wasm-runtime-flags.js +106 -0
  206. package/dist/extraction/wasm-runtime-flags.js.map +1 -0
  207. package/dist/graph/index.d.ts +8 -0
  208. package/dist/graph/index.d.ts.map +1 -0
  209. package/dist/graph/index.js +13 -0
  210. package/dist/graph/index.js.map +1 -0
  211. package/dist/graph/queries.d.ts +106 -0
  212. package/dist/graph/queries.d.ts.map +1 -0
  213. package/dist/graph/queries.js +366 -0
  214. package/dist/graph/queries.js.map +1 -0
  215. package/dist/graph/traversal.d.ts +127 -0
  216. package/dist/graph/traversal.d.ts.map +1 -0
  217. package/dist/graph/traversal.js +531 -0
  218. package/dist/graph/traversal.js.map +1 -0
  219. package/dist/index.d.ts +551 -0
  220. package/dist/index.d.ts.map +1 -0
  221. package/dist/index.js +1165 -0
  222. package/dist/index.js.map +1 -0
  223. package/dist/installer/config-writer.d.ts +28 -0
  224. package/dist/installer/config-writer.d.ts.map +1 -0
  225. package/dist/installer/config-writer.js +91 -0
  226. package/dist/installer/config-writer.js.map +1 -0
  227. package/dist/installer/index.d.ts +87 -0
  228. package/dist/installer/index.d.ts.map +1 -0
  229. package/dist/installer/index.js +409 -0
  230. package/dist/installer/index.js.map +1 -0
  231. package/dist/installer/instructions-template.d.ts +18 -0
  232. package/dist/installer/instructions-template.d.ts.map +1 -0
  233. package/dist/installer/instructions-template.js +21 -0
  234. package/dist/installer/instructions-template.js.map +1 -0
  235. package/dist/installer/targets/claude.d.ts +88 -0
  236. package/dist/installer/targets/claude.d.ts.map +1 -0
  237. package/dist/installer/targets/claude.js +582 -0
  238. package/dist/installer/targets/claude.js.map +1 -0
  239. package/dist/installer/targets/registry.d.ts +19 -0
  240. package/dist/installer/targets/registry.d.ts.map +1 -0
  241. package/dist/installer/targets/registry.js +31 -0
  242. package/dist/installer/targets/registry.js.map +1 -0
  243. package/dist/installer/targets/shared.d.ts +62 -0
  244. package/dist/installer/targets/shared.d.ts.map +1 -0
  245. package/dist/installer/targets/shared.js +207 -0
  246. package/dist/installer/targets/shared.js.map +1 -0
  247. package/dist/installer/targets/types.d.ts +76 -0
  248. package/dist/installer/targets/types.d.ts.map +1 -0
  249. package/dist/installer/targets/types.js +12 -0
  250. package/dist/installer/targets/types.js.map +1 -0
  251. package/dist/isolation/worktree.d.ts +65 -0
  252. package/dist/isolation/worktree.d.ts.map +1 -0
  253. package/dist/isolation/worktree.js +231 -0
  254. package/dist/isolation/worktree.js.map +1 -0
  255. package/dist/mcp/daemon-paths.d.ts +46 -0
  256. package/dist/mcp/daemon-paths.d.ts.map +1 -0
  257. package/dist/mcp/daemon-paths.js +125 -0
  258. package/dist/mcp/daemon-paths.js.map +1 -0
  259. package/dist/mcp/daemon.d.ts +161 -0
  260. package/dist/mcp/daemon.d.ts.map +1 -0
  261. package/dist/mcp/daemon.js +403 -0
  262. package/dist/mcp/daemon.js.map +1 -0
  263. package/dist/mcp/engine.d.ts +105 -0
  264. package/dist/mcp/engine.d.ts.map +1 -0
  265. package/dist/mcp/engine.js +270 -0
  266. package/dist/mcp/engine.js.map +1 -0
  267. package/dist/mcp/index.d.ts +112 -0
  268. package/dist/mcp/index.d.ts.map +1 -0
  269. package/dist/mcp/index.js +477 -0
  270. package/dist/mcp/index.js.map +1 -0
  271. package/dist/mcp/proxy.d.ts +81 -0
  272. package/dist/mcp/proxy.d.ts.map +1 -0
  273. package/dist/mcp/proxy.js +510 -0
  274. package/dist/mcp/proxy.js.map +1 -0
  275. package/dist/mcp/server-instructions.d.ts +18 -0
  276. package/dist/mcp/server-instructions.d.ts.map +1 -0
  277. package/dist/mcp/server-instructions.js +77 -0
  278. package/dist/mcp/server-instructions.js.map +1 -0
  279. package/dist/mcp/session.d.ts +77 -0
  280. package/dist/mcp/session.d.ts.map +1 -0
  281. package/dist/mcp/session.js +294 -0
  282. package/dist/mcp/session.js.map +1 -0
  283. package/dist/mcp/spec-tools.d.ts +39 -0
  284. package/dist/mcp/spec-tools.d.ts.map +1 -0
  285. package/dist/mcp/spec-tools.js +326 -0
  286. package/dist/mcp/spec-tools.js.map +1 -0
  287. package/dist/mcp/tools.d.ts +404 -0
  288. package/dist/mcp/tools.d.ts.map +1 -0
  289. package/dist/mcp/tools.js +3066 -0
  290. package/dist/mcp/tools.js.map +1 -0
  291. package/dist/mcp/transport.d.ts +188 -0
  292. package/dist/mcp/transport.d.ts.map +1 -0
  293. package/dist/mcp/transport.js +343 -0
  294. package/dist/mcp/transport.js.map +1 -0
  295. package/dist/mcp/version.d.ts +19 -0
  296. package/dist/mcp/version.d.ts.map +1 -0
  297. package/dist/mcp/version.js +71 -0
  298. package/dist/mcp/version.js.map +1 -0
  299. package/dist/resolution/callback-synthesizer.d.ts +10 -0
  300. package/dist/resolution/callback-synthesizer.d.ts.map +1 -0
  301. package/dist/resolution/callback-synthesizer.js +1300 -0
  302. package/dist/resolution/callback-synthesizer.js.map +1 -0
  303. package/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
  304. package/dist/resolution/frameworks/cargo-workspace.d.ts.map +1 -0
  305. package/dist/resolution/frameworks/cargo-workspace.js +225 -0
  306. package/dist/resolution/frameworks/cargo-workspace.js.map +1 -0
  307. package/dist/resolution/frameworks/csharp.d.ts +8 -0
  308. package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
  309. package/dist/resolution/frameworks/csharp.js +241 -0
  310. package/dist/resolution/frameworks/csharp.js.map +1 -0
  311. package/dist/resolution/frameworks/drupal.d.ts +51 -0
  312. package/dist/resolution/frameworks/drupal.d.ts.map +1 -0
  313. package/dist/resolution/frameworks/drupal.js +367 -0
  314. package/dist/resolution/frameworks/drupal.js.map +1 -0
  315. package/dist/resolution/frameworks/expo-modules.d.ts +3 -0
  316. package/dist/resolution/frameworks/expo-modules.d.ts.map +1 -0
  317. package/dist/resolution/frameworks/expo-modules.js +143 -0
  318. package/dist/resolution/frameworks/expo-modules.js.map +1 -0
  319. package/dist/resolution/frameworks/express.d.ts +8 -0
  320. package/dist/resolution/frameworks/express.d.ts.map +1 -0
  321. package/dist/resolution/frameworks/express.js +308 -0
  322. package/dist/resolution/frameworks/express.js.map +1 -0
  323. package/dist/resolution/frameworks/fabric.d.ts +3 -0
  324. package/dist/resolution/frameworks/fabric.d.ts.map +1 -0
  325. package/dist/resolution/frameworks/fabric.js +354 -0
  326. package/dist/resolution/frameworks/fabric.js.map +1 -0
  327. package/dist/resolution/frameworks/go.d.ts +8 -0
  328. package/dist/resolution/frameworks/go.d.ts.map +1 -0
  329. package/dist/resolution/frameworks/go.js +161 -0
  330. package/dist/resolution/frameworks/go.js.map +1 -0
  331. package/dist/resolution/frameworks/index.d.ts +48 -0
  332. package/dist/resolution/frameworks/index.d.ts.map +1 -0
  333. package/dist/resolution/frameworks/index.js +161 -0
  334. package/dist/resolution/frameworks/index.js.map +1 -0
  335. package/dist/resolution/frameworks/java.d.ts +8 -0
  336. package/dist/resolution/frameworks/java.d.ts.map +1 -0
  337. package/dist/resolution/frameworks/java.js +504 -0
  338. package/dist/resolution/frameworks/java.js.map +1 -0
  339. package/dist/resolution/frameworks/laravel.d.ts +13 -0
  340. package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
  341. package/dist/resolution/frameworks/laravel.js +257 -0
  342. package/dist/resolution/frameworks/laravel.js.map +1 -0
  343. package/dist/resolution/frameworks/nestjs.d.ts +26 -0
  344. package/dist/resolution/frameworks/nestjs.d.ts.map +1 -0
  345. package/dist/resolution/frameworks/nestjs.js +698 -0
  346. package/dist/resolution/frameworks/nestjs.js.map +1 -0
  347. package/dist/resolution/frameworks/play.d.ts +19 -0
  348. package/dist/resolution/frameworks/play.d.ts.map +1 -0
  349. package/dist/resolution/frameworks/play.js +111 -0
  350. package/dist/resolution/frameworks/play.js.map +1 -0
  351. package/dist/resolution/frameworks/python.d.ts +10 -0
  352. package/dist/resolution/frameworks/python.d.ts.map +1 -0
  353. package/dist/resolution/frameworks/python.js +396 -0
  354. package/dist/resolution/frameworks/python.js.map +1 -0
  355. package/dist/resolution/frameworks/react-native.d.ts +3 -0
  356. package/dist/resolution/frameworks/react-native.d.ts.map +1 -0
  357. package/dist/resolution/frameworks/react-native.js +360 -0
  358. package/dist/resolution/frameworks/react-native.js.map +1 -0
  359. package/dist/resolution/frameworks/react.d.ts +8 -0
  360. package/dist/resolution/frameworks/react.d.ts.map +1 -0
  361. package/dist/resolution/frameworks/react.js +365 -0
  362. package/dist/resolution/frameworks/react.js.map +1 -0
  363. package/dist/resolution/frameworks/ruby.d.ts +8 -0
  364. package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
  365. package/dist/resolution/frameworks/ruby.js +302 -0
  366. package/dist/resolution/frameworks/ruby.js.map +1 -0
  367. package/dist/resolution/frameworks/rust.d.ts +8 -0
  368. package/dist/resolution/frameworks/rust.d.ts.map +1 -0
  369. package/dist/resolution/frameworks/rust.js +304 -0
  370. package/dist/resolution/frameworks/rust.js.map +1 -0
  371. package/dist/resolution/frameworks/svelte.d.ts +9 -0
  372. package/dist/resolution/frameworks/svelte.d.ts.map +1 -0
  373. package/dist/resolution/frameworks/svelte.js +249 -0
  374. package/dist/resolution/frameworks/svelte.js.map +1 -0
  375. package/dist/resolution/frameworks/swift-objc.d.ts +37 -0
  376. package/dist/resolution/frameworks/swift-objc.d.ts.map +1 -0
  377. package/dist/resolution/frameworks/swift-objc.js +252 -0
  378. package/dist/resolution/frameworks/swift-objc.js.map +1 -0
  379. package/dist/resolution/frameworks/swift.d.ts +10 -0
  380. package/dist/resolution/frameworks/swift.d.ts.map +1 -0
  381. package/dist/resolution/frameworks/swift.js +400 -0
  382. package/dist/resolution/frameworks/swift.js.map +1 -0
  383. package/dist/resolution/frameworks/vue.d.ts +9 -0
  384. package/dist/resolution/frameworks/vue.d.ts.map +1 -0
  385. package/dist/resolution/frameworks/vue.js +306 -0
  386. package/dist/resolution/frameworks/vue.js.map +1 -0
  387. package/dist/resolution/go-module.d.ts +26 -0
  388. package/dist/resolution/go-module.d.ts.map +1 -0
  389. package/dist/resolution/go-module.js +78 -0
  390. package/dist/resolution/go-module.js.map +1 -0
  391. package/dist/resolution/import-resolver.d.ts +68 -0
  392. package/dist/resolution/import-resolver.d.ts.map +1 -0
  393. package/dist/resolution/import-resolver.js +1275 -0
  394. package/dist/resolution/import-resolver.js.map +1 -0
  395. package/dist/resolution/index.d.ts +117 -0
  396. package/dist/resolution/index.d.ts.map +1 -0
  397. package/dist/resolution/index.js +895 -0
  398. package/dist/resolution/index.js.map +1 -0
  399. package/dist/resolution/lru-cache.d.ts +24 -0
  400. package/dist/resolution/lru-cache.d.ts.map +1 -0
  401. package/dist/resolution/lru-cache.js +62 -0
  402. package/dist/resolution/lru-cache.js.map +1 -0
  403. package/dist/resolution/name-matcher.d.ts +32 -0
  404. package/dist/resolution/name-matcher.d.ts.map +1 -0
  405. package/dist/resolution/name-matcher.js +596 -0
  406. package/dist/resolution/name-matcher.js.map +1 -0
  407. package/dist/resolution/path-aliases.d.ts +68 -0
  408. package/dist/resolution/path-aliases.d.ts.map +1 -0
  409. package/dist/resolution/path-aliases.js +238 -0
  410. package/dist/resolution/path-aliases.js.map +1 -0
  411. package/dist/resolution/spec-link-resolver.d.ts +103 -0
  412. package/dist/resolution/spec-link-resolver.d.ts.map +1 -0
  413. package/dist/resolution/spec-link-resolver.js +259 -0
  414. package/dist/resolution/spec-link-resolver.js.map +1 -0
  415. package/dist/resolution/strip-comments.d.ts +27 -0
  416. package/dist/resolution/strip-comments.d.ts.map +1 -0
  417. package/dist/resolution/strip-comments.js +441 -0
  418. package/dist/resolution/strip-comments.js.map +1 -0
  419. package/dist/resolution/swift-objc-bridge.d.ts +134 -0
  420. package/dist/resolution/swift-objc-bridge.d.ts.map +1 -0
  421. package/dist/resolution/swift-objc-bridge.js +256 -0
  422. package/dist/resolution/swift-objc-bridge.js.map +1 -0
  423. package/dist/resolution/types.d.ts +216 -0
  424. package/dist/resolution/types.d.ts.map +1 -0
  425. package/dist/resolution/types.js +8 -0
  426. package/dist/resolution/types.js.map +1 -0
  427. package/dist/resolution/workspace-packages.d.ts +48 -0
  428. package/dist/resolution/workspace-packages.d.ts.map +1 -0
  429. package/dist/resolution/workspace-packages.js +208 -0
  430. package/dist/resolution/workspace-packages.js.map +1 -0
  431. package/dist/search/query-parser.d.ts +57 -0
  432. package/dist/search/query-parser.d.ts.map +1 -0
  433. package/dist/search/query-parser.js +177 -0
  434. package/dist/search/query-parser.js.map +1 -0
  435. package/dist/search/query-utils.d.ts +71 -0
  436. package/dist/search/query-utils.d.ts.map +1 -0
  437. package/dist/search/query-utils.js +380 -0
  438. package/dist/search/query-utils.js.map +1 -0
  439. package/dist/server/cli.js +152 -0
  440. package/dist/server/index.js +12 -0
  441. package/dist/server/ingest/index.js +18 -0
  442. package/dist/server/ingest/ingestor.js +406 -0
  443. package/dist/server/ingest/parser.js +104 -0
  444. package/dist/server/ingest/pricing.js +78 -0
  445. package/dist/server/ingest/types.js +9 -0
  446. package/dist/server/ingest/watcher.js +77 -0
  447. package/dist/server/package.json +3 -0
  448. package/dist/server/project-registry.js +101 -0
  449. package/dist/server/routes/claude.js +480 -0
  450. package/dist/server/routes/graph.js +149 -0
  451. package/dist/server/routes/memory.js +272 -0
  452. package/dist/server/routes/projects.js +197 -0
  453. package/dist/server/routes/spec.js +105 -0
  454. package/dist/server/routes/status.js +35 -0
  455. package/dist/server/routes/workflow.js +184 -0
  456. package/dist/server/server.js +202 -0
  457. package/dist/sync/git-hooks.d.ts +45 -0
  458. package/dist/sync/git-hooks.d.ts.map +1 -0
  459. package/dist/sync/git-hooks.js +225 -0
  460. package/dist/sync/git-hooks.js.map +1 -0
  461. package/dist/sync/index.d.ts +19 -0
  462. package/dist/sync/index.d.ts.map +1 -0
  463. package/dist/sync/index.js +35 -0
  464. package/dist/sync/index.js.map +1 -0
  465. package/dist/sync/watch-policy.d.ts +48 -0
  466. package/dist/sync/watch-policy.d.ts.map +1 -0
  467. package/dist/sync/watch-policy.js +124 -0
  468. package/dist/sync/watch-policy.js.map +1 -0
  469. package/dist/sync/watcher.d.ts +283 -0
  470. package/dist/sync/watcher.d.ts.map +1 -0
  471. package/dist/sync/watcher.js +606 -0
  472. package/dist/sync/watcher.js.map +1 -0
  473. package/dist/sync/worktree.d.ts +54 -0
  474. package/dist/sync/worktree.d.ts.map +1 -0
  475. package/dist/sync/worktree.js +137 -0
  476. package/dist/sync/worktree.js.map +1 -0
  477. package/dist/types.d.ts +623 -0
  478. package/dist/types.d.ts.map +1 -0
  479. package/dist/types.js +108 -0
  480. package/dist/types.js.map +1 -0
  481. package/dist/ui/glyphs.d.ts +42 -0
  482. package/dist/ui/glyphs.d.ts.map +1 -0
  483. package/dist/ui/glyphs.js +78 -0
  484. package/dist/ui/glyphs.js.map +1 -0
  485. package/dist/ui/shimmer-progress.d.ts +11 -0
  486. package/dist/ui/shimmer-progress.d.ts.map +1 -0
  487. package/dist/ui/shimmer-progress.js +90 -0
  488. package/dist/ui/shimmer-progress.js.map +1 -0
  489. package/dist/ui/shimmer-worker.d.ts +2 -0
  490. package/dist/ui/shimmer-worker.d.ts.map +1 -0
  491. package/dist/ui/shimmer-worker.js +118 -0
  492. package/dist/ui/shimmer-worker.js.map +1 -0
  493. package/dist/ui/types.d.ts +17 -0
  494. package/dist/ui/types.d.ts.map +1 -0
  495. package/dist/ui/types.js +3 -0
  496. package/dist/ui/types.js.map +1 -0
  497. package/dist/utils.d.ts +205 -0
  498. package/dist/utils.d.ts.map +1 -0
  499. package/dist/utils.js +549 -0
  500. package/dist/utils.js.map +1 -0
  501. package/dist/web/chunk-2YZXEHZ2.js +1 -0
  502. package/dist/web/chunk-3GIC555L.js +18 -0
  503. package/dist/web/chunk-3IIIGRMT.js +1 -0
  504. package/dist/web/chunk-47QYKLE5.js +1 -0
  505. package/dist/web/chunk-4LHBWWP7.js +1 -0
  506. package/dist/web/chunk-4OAZLD5W.js +1 -0
  507. package/dist/web/chunk-5OQKAJAE.js +1 -0
  508. package/dist/web/chunk-7B525GKQ.js +1 -0
  509. package/dist/web/chunk-BPDXCOOZ.js +1 -0
  510. package/dist/web/chunk-DT37HTZB.js +1 -0
  511. package/dist/web/chunk-EIMUHJND.js +1 -0
  512. package/dist/web/chunk-FTESTUEO.js +1 -0
  513. package/dist/web/chunk-GLJZV6MU.js +1 -0
  514. package/dist/web/chunk-I7LS67U5.js +1 -0
  515. package/dist/web/chunk-L4TVIPSR.js +1 -0
  516. package/dist/web/chunk-MASCULC2.js +1 -0
  517. package/dist/web/chunk-MW7ICSRM.js +1 -0
  518. package/dist/web/chunk-OI5VP2A3.js +1 -0
  519. package/dist/web/chunk-RA6EBF6I.js +1 -0
  520. package/dist/web/chunk-RP3WU5Y6.js +1 -0
  521. package/dist/web/chunk-RQDRMTXN.js +1 -0
  522. package/dist/web/chunk-TQMT6UDU.js +1 -0
  523. package/dist/web/chunk-U7IYOV7T.js +1 -0
  524. package/dist/web/chunk-UE227MWF.js +1 -0
  525. package/dist/web/chunk-WV573J4K.js +1 -0
  526. package/dist/web/chunk-WVCKOJZL.js +4 -0
  527. package/dist/web/chunk-XZKLVPHE.js +1 -0
  528. package/dist/web/chunk-ZABKKHJ3.js +1 -0
  529. package/dist/web/favicon-16.png +0 -0
  530. package/dist/web/favicon-180.png +0 -0
  531. package/dist/web/favicon-32.png +0 -0
  532. package/dist/web/favicon-512.png +0 -0
  533. package/dist/web/favicon-small.svg +15 -0
  534. package/dist/web/favicon.ico +0 -0
  535. package/dist/web/favicon.svg +20 -0
  536. package/dist/web/index.html +145 -0
  537. package/dist/web/main-RI5CO5Z4.js +1 -0
  538. package/dist/web/styles-CYN7IKT4.css +1 -0
  539. package/dist/workflows/condition-evaluator.d.ts +75 -0
  540. package/dist/workflows/condition-evaluator.d.ts.map +1 -0
  541. package/dist/workflows/condition-evaluator.js +282 -0
  542. package/dist/workflows/condition-evaluator.js.map +1 -0
  543. package/dist/workflows/defaults/index.d.ts +26 -0
  544. package/dist/workflows/defaults/index.d.ts.map +1 -0
  545. package/dist/workflows/defaults/index.js +94 -0
  546. package/dist/workflows/defaults/index.js.map +1 -0
  547. package/dist/workflows/defaults/spec-fix.yaml +110 -0
  548. package/dist/workflows/defaults/spec-implement.yaml +150 -0
  549. package/dist/workflows/defaults/spec-relink.yaml +81 -0
  550. package/dist/workflows/defaults/spec-verify.yaml +51 -0
  551. package/dist/workflows/discovery.d.ts +46 -0
  552. package/dist/workflows/discovery.d.ts.map +1 -0
  553. package/dist/workflows/discovery.js +193 -0
  554. package/dist/workflows/discovery.js.map +1 -0
  555. package/dist/workflows/executor.d.ts +83 -0
  556. package/dist/workflows/executor.d.ts.map +1 -0
  557. package/dist/workflows/executor.js +623 -0
  558. package/dist/workflows/executor.js.map +1 -0
  559. package/dist/workflows/runners/approval.d.ts +18 -0
  560. package/dist/workflows/runners/approval.d.ts.map +1 -0
  561. package/dist/workflows/runners/approval.js +34 -0
  562. package/dist/workflows/runners/approval.js.map +1 -0
  563. package/dist/workflows/runners/bash.d.ts +13 -0
  564. package/dist/workflows/runners/bash.d.ts.map +1 -0
  565. package/dist/workflows/runners/bash.js +143 -0
  566. package/dist/workflows/runners/bash.js.map +1 -0
  567. package/dist/workflows/runners/cancel.d.ts +10 -0
  568. package/dist/workflows/runners/cancel.d.ts.map +1 -0
  569. package/dist/workflows/runners/cancel.js +19 -0
  570. package/dist/workflows/runners/cancel.js.map +1 -0
  571. package/dist/workflows/runners/prompt.d.ts +28 -0
  572. package/dist/workflows/runners/prompt.d.ts.map +1 -0
  573. package/dist/workflows/runners/prompt.js +212 -0
  574. package/dist/workflows/runners/prompt.js.map +1 -0
  575. package/dist/workflows/runners/script.d.ts +17 -0
  576. package/dist/workflows/runners/script.d.ts.map +1 -0
  577. package/dist/workflows/runners/script.js +155 -0
  578. package/dist/workflows/runners/script.js.map +1 -0
  579. package/dist/workflows/runners/types.d.ts +51 -0
  580. package/dist/workflows/runners/types.d.ts.map +1 -0
  581. package/dist/workflows/runners/types.js +13 -0
  582. package/dist/workflows/runners/types.js.map +1 -0
  583. package/dist/workflows/schemas/workflow.d.ts +166 -0
  584. package/dist/workflows/schemas/workflow.d.ts.map +1 -0
  585. package/dist/workflows/schemas/workflow.js +437 -0
  586. package/dist/workflows/schemas/workflow.js.map +1 -0
  587. package/hooks/hooks.json +27 -0
  588. package/package.json +67 -0
  589. package/scripts/add-lang/bench.sh +60 -0
  590. package/scripts/add-lang/check-grammar.mjs +75 -0
  591. package/scripts/add-lang/dump-ast.mjs +103 -0
  592. package/scripts/add-lang/verify-extraction.mjs +70 -0
  593. package/scripts/agent-eval/arms-F.sh +21 -0
  594. package/scripts/agent-eval/arms-matrix.sh +37 -0
  595. package/scripts/agent-eval/audit.sh +68 -0
  596. package/scripts/agent-eval/bench-readme.sh +28 -0
  597. package/scripts/agent-eval/bench-why-repo.sh +22 -0
  598. package/scripts/agent-eval/block-read-hook.sh +19 -0
  599. package/scripts/agent-eval/hook-settings.json +15 -0
  600. package/scripts/agent-eval/itrun.sh +120 -0
  601. package/scripts/agent-eval/parse-arms.mjs +116 -0
  602. package/scripts/agent-eval/parse-bench-readme.mjs +84 -0
  603. package/scripts/agent-eval/parse-run.mjs +45 -0
  604. package/scripts/agent-eval/parse-session.mjs +93 -0
  605. package/scripts/agent-eval/probe-context.mjs +21 -0
  606. package/scripts/agent-eval/probe-explore.mjs +40 -0
  607. package/scripts/agent-eval/probe-node.mjs +20 -0
  608. package/scripts/agent-eval/probe-sweep.mjs +119 -0
  609. package/scripts/agent-eval/probe-trace.mjs +20 -0
  610. package/scripts/agent-eval/run-agent.sh +34 -0
  611. package/scripts/agent-eval/run-all.sh +67 -0
  612. package/scripts/agent-eval/run-arms.sh +56 -0
  613. package/scripts/agent-eval/seq-matrix.mjs +137 -0
  614. package/scripts/build-bundle.sh +118 -0
  615. package/scripts/build-server-bundle.mjs +80 -0
  616. package/scripts/build-web-bundle.mjs +66 -0
  617. package/scripts/extract-release-notes.mjs +130 -0
  618. package/scripts/local-install.sh +41 -0
  619. package/scripts/npm-sdk.js +75 -0
  620. package/scripts/npm-shim.js +246 -0
  621. package/scripts/offline-install.ps1 +148 -0
  622. package/scripts/offline-install.sh +136 -0
  623. package/scripts/pack-npm.sh +119 -0
  624. package/scripts/prepare-release.mjs +270 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Spec layer routes — list / fetch / link assert / link verify / drift queue.
3
+ *
4
+ * Every route is project-scoped via `?project=<slug>` (falls back to the
5
+ * boot-time primary). Returns 409 / `no_project` when neither is selectable.
6
+ */
7
+ async function resolveCg(app, req, reply) {
8
+ const cg = await app.activeCg(req);
9
+ if (!cg) {
10
+ reply.code(409).send({ error: 'no project selected', code: 'no_project' });
11
+ return null;
12
+ }
13
+ return cg;
14
+ }
15
+ export async function registerSpecRoutes(app) {
16
+ app.get('/api/specs', async (req, reply) => {
17
+ const cg = await resolveCg(app, req, reply);
18
+ if (!cg)
19
+ return;
20
+ const docs = cg.getSpecQueries().getAllSpecs();
21
+ return { specs: docs };
22
+ });
23
+ app.get('/api/spec/:id', async (req, reply) => {
24
+ const cg = await resolveCg(app, req, reply);
25
+ if (!cg)
26
+ return;
27
+ const sq = cg.getSpecQueries();
28
+ const spec = sq.getSpecById(req.params.id);
29
+ if (!spec)
30
+ return reply.code(404).send({ error: 'spec not found' });
31
+ const parent = spec.parentId ? sq.getSpecById(spec.parentId) : null;
32
+ const children = sq.getSpecsByParent(spec.id);
33
+ const siblings = parent ? sq.getSpecsByParent(parent.id).filter((s) => s.id !== spec.id) : [];
34
+ const links = sq.getLinksBySpec(spec.id);
35
+ return { spec, parent, siblings, children, links };
36
+ });
37
+ app.get('/api/drift', async (req, reply) => {
38
+ const cg = await resolveCg(app, req, reply);
39
+ if (!cg)
40
+ return;
41
+ const sq = cg.getSpecQueries();
42
+ const validStates = [
43
+ 'drafted', 'implementing', 'implemented', 'verified',
44
+ 'drifted', 'broken', 'orphaned',
45
+ ];
46
+ const requested = (req.query.state ?? 'drifted,broken,orphaned')
47
+ .split(',')
48
+ .map((s) => s.trim())
49
+ .filter((s) => validStates.includes(s));
50
+ const limit = Math.min(parseInt(req.query.limit ?? '100', 10) || 100, 500);
51
+ const links = sq.getLinksByState(requested).slice(0, limit);
52
+ const out = links.map((l) => {
53
+ const spec = sq.getSpecById(l.specId);
54
+ return { ...l, specTitle: spec?.title ?? null };
55
+ });
56
+ return { links: out };
57
+ });
58
+ app.post('/api/spec/link-assert', async (req, reply) => {
59
+ const cg = await resolveCg(app, req, reply);
60
+ if (!cg)
61
+ return;
62
+ const body = req.body;
63
+ if (!body?.spec_id || !body.target_file_path || !body.target_qualified_name) {
64
+ return reply.code(400).send({ error: 'spec_id, target_file_path, target_qualified_name required' });
65
+ }
66
+ const sq = cg.getSpecQueries();
67
+ const spec = sq.getSpecById(body.spec_id);
68
+ if (!spec)
69
+ return reply.code(404).send({ error: 'spec not found' });
70
+ const now = Date.now();
71
+ const id = sq.upsertSpecLink({
72
+ specId: body.spec_id,
73
+ targetFilePath: body.target_file_path,
74
+ targetQualifiedName: body.target_qualified_name,
75
+ targetNodeKind: body.target_node_kind ?? 'function',
76
+ resolvedNodeId: undefined,
77
+ kind: body.kind ?? 'implements',
78
+ state: 'implemented',
79
+ driftAxis: null,
80
+ specHashAtLink: spec.contentHash,
81
+ nodeSigAtLink: undefined,
82
+ provenance: 'agent-asserted',
83
+ confidence: 1.0,
84
+ createdAt: now,
85
+ updatedAt: now,
86
+ });
87
+ cg.getSpecLinkResolver().resolveLinksForFiles([body.target_file_path]);
88
+ return { id, ok: true };
89
+ });
90
+ app.post('/api/spec/link-verify', async (req, reply) => {
91
+ const cg = await resolveCg(app, req, reply);
92
+ if (!cg)
93
+ return;
94
+ const body = req.body;
95
+ if (typeof body?.link_id !== 'number' || (body.result !== 'pass' && body.result !== 'fail')) {
96
+ return reply.code(400).send({ error: 'link_id (number) and result ("pass"|"fail") required' });
97
+ }
98
+ const sq = cg.getSpecQueries();
99
+ const link = sq.getLinkById(body.link_id);
100
+ if (!link)
101
+ return reply.code(404).send({ error: 'link not found' });
102
+ sq.updateSpecLinkState(body.link_id, body.result === 'pass' ? 'verified' : 'broken', null);
103
+ return { ok: true, state: body.result === 'pass' ? 'verified' : 'broken' };
104
+ });
105
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * GET /api/status — backend, journal mode, node/edge counts, drift count,
3
+ * last index time. Drives the UI's persistent status strip.
4
+ *
5
+ * Project-scoped: accepts `?project=<slug>` and serves the matching
6
+ * SpecShip instance from the registry. When no project is selectable
7
+ * (no `?project=`, no primary), returns a 409 with `code: 'no_project'`
8
+ * so the UI can show the picker without blowing up.
9
+ */
10
+ export async function registerStatusRoutes(app) {
11
+ app.get('/api/status', async (req, reply) => {
12
+ const cg = await app.activeCg(req);
13
+ if (!cg) {
14
+ return reply.code(409).send({ error: 'no project selected', code: 'no_project' });
15
+ }
16
+ const stats = cg.getStats();
17
+ const lastIndexed = cg.getLastIndexedAt();
18
+ const drift = cg
19
+ .getSpecQueries()
20
+ .getLinksByState(['drifted', 'broken', 'orphaned']).length;
21
+ return {
22
+ projectPath: cg.getProjectRoot ? cg.getProjectRoot() : '',
23
+ backend: cg.getBackend(),
24
+ journalMode: cg.getJournalMode(),
25
+ nodeCount: stats.nodeCount,
26
+ edgeCount: stats.edgeCount,
27
+ fileCount: stats.fileCount,
28
+ drift,
29
+ lastIndexed: lastIndexed != null ? new Date(lastIndexed).toISOString() : null,
30
+ nodesByKind: stats.nodesByKind,
31
+ filesByLanguage: stats.filesByLanguage,
32
+ dbSizeBytes: stats.dbSizeBytes,
33
+ };
34
+ });
35
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Workflow routes — discover / run / resume / cancel / approve / reject /
3
+ * runs list / run detail + SSE event stream.
4
+ *
5
+ * All project-scoped via `?project=<slug>` (falls back to primary). Each
6
+ * handler resolves the active SpecShip instance from the registry and
7
+ * constructs the WorktreeProvider + WorkflowExecutor on demand against
8
+ * that instance's queries. Construction is cheap (both classes just stash
9
+ * references), and pinning a single executor across all projects would
10
+ * tie the entire surface to whichever instance loaded first.
11
+ *
12
+ * The SSE endpoint streams workflow_events as they're appended to the DB
13
+ * (polling 500ms). For v1 polling the same SQLite the executor writes to is
14
+ * faster + more reliable than wiring an in-process event bus across packages.
15
+ */
16
+ async function resolveCg(app, req, reply) {
17
+ const cg = await app.activeCg(req);
18
+ if (!cg) {
19
+ reply.code(409).send({ error: 'no project selected', code: 'no_project' });
20
+ return null;
21
+ }
22
+ return cg;
23
+ }
24
+ export async function registerWorkflowRoutes(app) {
25
+ // Lazy import — keeps the server bootable even if the workflow engine
26
+ // is disabled in the current build profile.
27
+ const { discoverWorkflows, loadWorkflowByName } = await import('@selvakumaresra/specship/dist/workflows/discovery.js');
28
+ const { WorkflowExecutor } = await import('@selvakumaresra/specship/dist/workflows/executor.js');
29
+ const { WorktreeProvider } = await import('@selvakumaresra/specship/dist/isolation/worktree.js');
30
+ const executorCache = new WeakMap();
31
+ /** Build (or fetch cached) executor + worktree provider for a project. */
32
+ function executorFor(cg) {
33
+ const sq = cg.getSpecQueries();
34
+ const cached = executorCache.get(sq);
35
+ if (cached)
36
+ return { sq, executor: cached.executor, projectRoot: cached.projectRoot };
37
+ const projectRoot = cg.getProjectRoot ? cg.getProjectRoot() : process.cwd();
38
+ const worktrees = new WorktreeProvider(sq);
39
+ const executor = new WorkflowExecutor(sq, worktrees);
40
+ executorCache.set(sq, { executor, projectRoot });
41
+ return { sq, executor, projectRoot };
42
+ }
43
+ app.get('/api/workflows', async (req, reply) => {
44
+ const cg = await resolveCg(app, req, reply);
45
+ if (!cg)
46
+ return;
47
+ const { projectRoot } = executorFor(cg);
48
+ return discoverWorkflows(projectRoot);
49
+ });
50
+ app.post('/api/workflows/runs', async (req, reply) => {
51
+ const cg = await resolveCg(app, req, reply);
52
+ if (!cg)
53
+ return;
54
+ const { executor, projectRoot } = executorFor(cg);
55
+ const body = req.body;
56
+ if (!body?.workflowName)
57
+ return reply.code(400).send({ error: 'workflowName required' });
58
+ const loaded = loadWorkflowByName(projectRoot, body.workflowName);
59
+ if (!loaded)
60
+ return reply.code(404).send({ error: 'workflow not found' });
61
+ const startPromise = executor.start(loaded.workflow, {
62
+ projectRoot,
63
+ inputs: body.inputs,
64
+ variables: body.variables,
65
+ });
66
+ const result = await Promise.race([
67
+ startPromise,
68
+ new Promise((resolve) => setTimeout(() => resolve({ run: { id: 'pending', status: 'starting' } }), 50)),
69
+ ]);
70
+ startPromise.catch(() => { });
71
+ return { runId: result.run.id, status: result.run.status };
72
+ });
73
+ app.get('/api/workflows/runs', async (req, reply) => {
74
+ const cg = await resolveCg(app, req, reply);
75
+ if (!cg)
76
+ return;
77
+ const { sq } = executorFor(cg);
78
+ const limit = Math.min(parseInt(req.query.limit ?? '50', 10) || 50, 500);
79
+ return { runs: sq.getAllWorkflowRuns(limit) };
80
+ });
81
+ app.get('/api/workflows/runs/:id', async (req, reply) => {
82
+ const cg = await resolveCg(app, req, reply);
83
+ if (!cg)
84
+ return;
85
+ const { sq } = executorFor(cg);
86
+ const run = sq.getWorkflowRunById(req.params.id);
87
+ if (!run)
88
+ return reply.code(404).send({ error: 'run not found' });
89
+ const events = sq.getEventsByRun(req.params.id, 500);
90
+ return { run, events };
91
+ });
92
+ /**
93
+ * SSE event stream. Polls the events table every 500ms for any events
94
+ * newer than the last id sent. Closes when the run hits a terminal state.
95
+ */
96
+ app.get('/api/workflows/runs/:id/events', async (req, reply) => {
97
+ const cg = await resolveCg(app, req, reply);
98
+ if (!cg)
99
+ return;
100
+ const { sq } = executorFor(cg);
101
+ const runId = req.params.id;
102
+ let lastId = parseInt(req.query.since ?? '0', 10) || 0;
103
+ reply.raw.setHeader('Content-Type', 'text/event-stream');
104
+ reply.raw.setHeader('Cache-Control', 'no-cache');
105
+ reply.raw.setHeader('Connection', 'keep-alive');
106
+ reply.raw.flushHeaders();
107
+ let closed = false;
108
+ req.raw.on('close', () => { closed = true; });
109
+ const tick = async () => {
110
+ if (closed)
111
+ return;
112
+ const events = sq.getEventsByRun(runId, 1000);
113
+ const fresh = events.filter((e) => e.id > lastId);
114
+ for (const e of fresh) {
115
+ reply.raw.write(`id: ${e.id}\n`);
116
+ reply.raw.write(`event: ${e.eventType}\n`);
117
+ reply.raw.write(`data: ${JSON.stringify(e)}\n\n`);
118
+ lastId = e.id;
119
+ }
120
+ const run = sq.getWorkflowRunById(runId);
121
+ if (!run || ['completed', 'failed', 'cancelled'].includes(run.status)) {
122
+ reply.raw.write(`event: done\ndata: ${JSON.stringify({ status: run?.status })}\n\n`);
123
+ reply.raw.end();
124
+ return;
125
+ }
126
+ setTimeout(() => { void tick(); }, 500);
127
+ };
128
+ void tick();
129
+ });
130
+ app.post('/api/workflows/runs/:id/approve', async (req, reply) => {
131
+ const cg = await resolveCg(app, req, reply);
132
+ if (!cg)
133
+ return;
134
+ const { executor } = executorFor(cg);
135
+ try {
136
+ executor.approve(req.params.id, req.body?.comment);
137
+ return { ok: true };
138
+ }
139
+ catch (err) {
140
+ return reply.code(400).send({ error: err instanceof Error ? err.message : String(err) });
141
+ }
142
+ });
143
+ app.post('/api/workflows/runs/:id/reject', async (req, reply) => {
144
+ const cg = await resolveCg(app, req, reply);
145
+ if (!cg)
146
+ return;
147
+ const { executor } = executorFor(cg);
148
+ try {
149
+ executor.reject(req.params.id, req.body?.reason);
150
+ return { ok: true };
151
+ }
152
+ catch (err) {
153
+ return reply.code(400).send({ error: err instanceof Error ? err.message : String(err) });
154
+ }
155
+ });
156
+ app.post('/api/workflows/runs/:id/cancel', async (req, reply) => {
157
+ const cg = await resolveCg(app, req, reply);
158
+ if (!cg)
159
+ return;
160
+ const { executor } = executorFor(cg);
161
+ try {
162
+ executor.cancel(req.params.id, req.body?.reason);
163
+ return { ok: true };
164
+ }
165
+ catch (err) {
166
+ return reply.code(400).send({ error: err instanceof Error ? err.message : String(err) });
167
+ }
168
+ });
169
+ app.post('/api/workflows/runs/:id/resume', async (req, reply) => {
170
+ const cg = await resolveCg(app, req, reply);
171
+ if (!cg)
172
+ return;
173
+ const { sq, executor, projectRoot } = executorFor(cg);
174
+ const run = sq.getWorkflowRunById(req.params.id);
175
+ if (!run)
176
+ return reply.code(404).send({ error: 'run not found' });
177
+ const loaded = loadWorkflowByName(projectRoot, run.workflowName);
178
+ if (!loaded)
179
+ return reply.code(404).send({ error: 'workflow definition missing' });
180
+ const promise = executor.resume(loaded.workflow, req.params.id, { projectRoot });
181
+ promise.catch(() => { });
182
+ return { ok: true };
183
+ });
184
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Fastify HTTP server for specship + SpecShip Desktop UI.
3
+ *
4
+ * Routes follow the design spec — `/api/graph/*`, `/api/spec/*`,
5
+ * `/api/drift`, `/api/workflows/*`, `/api/claude/*`. Each route group lives
6
+ * in its own file under `./routes/` and registers itself on a passed
7
+ * Fastify instance.
8
+ *
9
+ * Why Fastify: lighter than Express, faster, first-class TypeScript types,
10
+ * built-in JSON schema validation, plugins for CORS + SSE. The 30K LoC
11
+ * Archon UI port pulls ~20+ API routes — Fastify's plugin model keeps the
12
+ * registration code tidy.
13
+ */
14
+ import path from 'node:path';
15
+ import { existsSync, promises as fs } from 'node:fs';
16
+ import { fileURLToPath, pathToFileURL } from 'node:url';
17
+ import Fastify from 'fastify';
18
+ import cors from '@fastify/cors';
19
+ import fastifyStatic from '@fastify/static';
20
+ import { startWatcher } from './ingest/index.js';
21
+ import { ProjectRegistry } from './project-registry.js';
22
+ import { registerGraphRoutes } from './routes/graph.js';
23
+ import { registerSpecRoutes } from './routes/spec.js';
24
+ import { registerWorkflowRoutes } from './routes/workflow.js';
25
+ import { registerClaudeRoutes } from './routes/claude.js';
26
+ import { registerStatusRoutes } from './routes/status.js';
27
+ import { registerMemoryRoutes } from './routes/memory.js';
28
+ import { registerProjectsRoutes } from './routes/projects.js';
29
+ /**
30
+ * Lazy-import the specship core. Two delivery shapes are supported:
31
+ *
32
+ * 1. **Bundled** — the platform-specific npm tarball lays the compiled
33
+ * server out at `<bundle>/lib/dist/server/server.js` and the specship
34
+ * core at `<bundle>/lib/dist/index.js`. We try this relative path
35
+ * first so the bundled mode never depends on Node's package
36
+ * resolution finding `@selvakumaresra/specship` (it won't, the
37
+ * bundle stages a single package by name `@selvakumaresra/specship`).
38
+ *
39
+ * 2. **Workspace / dev** — `packages/server/dist/server.js` imports via
40
+ * the workspace `file:../..` dep. Falls through to the named import.
41
+ *
42
+ * The function caches the resolved module so the lookup only runs once.
43
+ */
44
+ let cachedSpecShip = null;
45
+ async function loadSpecShip() {
46
+ if (cachedSpecShip)
47
+ return cachedSpecShip;
48
+ // Bundled mode: dist/server/server.js → ../index.js (root dist/index.js).
49
+ try {
50
+ const here = path.dirname(fileURLToPath(import.meta.url));
51
+ const candidate = path.resolve(here, '..', 'index.js');
52
+ if (existsSync(candidate)) {
53
+ cachedSpecShip = (await import(pathToFileURL(candidate).href));
54
+ return cachedSpecShip;
55
+ }
56
+ }
57
+ catch { /* fall through */ }
58
+ // Workspace/dev: resolve via the named dep.
59
+ cachedSpecShip = await import('@selvakumaresra/specship');
60
+ return cachedSpecShip;
61
+ }
62
+ export async function createServer(options) {
63
+ const host = options.host ?? '127.0.0.1';
64
+ const port = options.port ?? 4242;
65
+ const verbose = options.verbose ?? false;
66
+ const app = Fastify({
67
+ logger: verbose
68
+ ? { transport: { target: 'pino-pretty', options: { translateTime: 'HH:MM:ss.l' } } }
69
+ : false,
70
+ });
71
+ if (options.cors !== false) {
72
+ // Permissive CORS for local dev. The server is bound to loopback by
73
+ // default, so the broad allowlist is fine — Browsers won't get to it
74
+ // from a non-localhost origin without explicit user override.
75
+ await app.register(cors, {
76
+ origin: true,
77
+ credentials: false,
78
+ });
79
+ }
80
+ // Lazy-load specship. Used as the open() impl for the registry, and
81
+ // (only when a primary path is set) to open the primary instance below.
82
+ const cgMod = await loadSpecShip();
83
+ const registry = new ProjectRegistry({ verbose }, (p) => cgMod.SpecShip.open(p));
84
+ // Primary project (optional). When set, specship-scoped routes default to
85
+ // it when no `?project=<slug>` is provided, and the analytics ingest
86
+ // hooks into its SQLite handle.
87
+ let primaryCg = null;
88
+ if (options.projectRoot) {
89
+ primaryCg = await registry.get(options.projectRoot);
90
+ if (!primaryCg && verbose) {
91
+ console.error(`[specship-server] primary project ${options.projectRoot} not initialized — booting projectless`);
92
+ }
93
+ }
94
+ // Start the JSONL ingest watcher in-process unless the caller already
95
+ // provided one or explicitly opted out. Hooks into the primary project's
96
+ // SQLite handle — when there's no primary, analytics endpoints will return
97
+ // 409 until one is set (typically the next server restart with -p).
98
+ let watcher = options.watcher ?? null;
99
+ let ownedWatcher = false;
100
+ if (!watcher && options.ingest !== false && primaryCg) {
101
+ const cgAny = primaryCg;
102
+ const dbHandle = cgAny.db?.getDb ? cgAny.db.getDb() : cgAny.queries?.db;
103
+ if (dbHandle) {
104
+ watcher = startWatcher(dbHandle, { verbose });
105
+ ownedWatcher = true;
106
+ if (verbose)
107
+ console.error('[specship-server] JSONL ingest watcher started');
108
+ }
109
+ }
110
+ else if (!primaryCg && options.ingest !== false && verbose) {
111
+ console.error('[specship-server] no primary project — analytics will be empty until one is set');
112
+ }
113
+ // Decorate the Fastify instance so route handlers can access shared state
114
+ // without globals or DI containers.
115
+ app.decorate('projects', registry);
116
+ app.decorate('primaryCg', primaryCg);
117
+ app.decorate('watcher', watcher);
118
+ // activeCg(req): resolve `?project=<slug>` → SpecShip instance, with the
119
+ // primary as fallback. Returns null when nothing is selectable; route
120
+ // handlers respond 409 in that case.
121
+ app.decorate('activeCg', async function (req) {
122
+ const q = (req.query ?? {});
123
+ if (q.project) {
124
+ const bySlug = await registry.getBySlug(q.project);
125
+ if (bySlug)
126
+ return bySlug;
127
+ }
128
+ if (q.projectPath) {
129
+ const byPath = await registry.get(q.projectPath);
130
+ if (byPath)
131
+ return byPath;
132
+ }
133
+ return primaryCg;
134
+ });
135
+ // Register route groups.
136
+ await registerStatusRoutes(app);
137
+ await registerGraphRoutes(app);
138
+ await registerSpecRoutes(app);
139
+ await registerWorkflowRoutes(app);
140
+ await registerClaudeRoutes(app);
141
+ await registerMemoryRoutes(app);
142
+ await registerProjectsRoutes(app);
143
+ // Optional: serve the built Angular UI from `webDir` and fall back to
144
+ // index.html for client-side routes. Must register AFTER the /api/*
145
+ // routes so they take precedence over the SPA wildcard.
146
+ if (options.webDir) {
147
+ const indexPath = path.join(options.webDir, 'index.html');
148
+ let indexBuffer = null;
149
+ try {
150
+ indexBuffer = await fs.readFile(indexPath);
151
+ }
152
+ catch {
153
+ if (verbose) {
154
+ console.error(`[specship-server] webDir provided but index.html not found at ${indexPath} — skipping static mount`);
155
+ }
156
+ }
157
+ if (indexBuffer) {
158
+ await app.register(fastifyStatic, {
159
+ root: options.webDir,
160
+ prefix: '/',
161
+ // index.html is served via the SPA fallback so it always reflects
162
+ // the latest bytes (even when a future hot-swap drops a new build).
163
+ index: false,
164
+ wildcard: false,
165
+ });
166
+ const cachedIndex = indexBuffer;
167
+ app.setNotFoundHandler((request, reply) => {
168
+ // Only fall back for browser GETs that aren't API requests. API
169
+ // 404s should stay 404s so the UI can surface them properly.
170
+ if (request.method !== 'GET') {
171
+ reply.code(404).send({ error: 'not found' });
172
+ return;
173
+ }
174
+ if (request.url.startsWith('/api/')) {
175
+ reply.code(404).send({ error: 'not found' });
176
+ return;
177
+ }
178
+ reply.code(200).type('text/html').send(cachedIndex);
179
+ });
180
+ if (verbose)
181
+ console.error(`[specship-server] serving SPA from ${options.webDir}`);
182
+ }
183
+ }
184
+ await app.listen({ host, port });
185
+ const url = `http://${host}:${port}`;
186
+ return {
187
+ app,
188
+ url,
189
+ host,
190
+ port,
191
+ stop: async () => {
192
+ if (ownedWatcher && watcher) {
193
+ try {
194
+ watcher.stop();
195
+ }
196
+ catch { /* ignore */ }
197
+ }
198
+ registry.closeAll();
199
+ await app.close();
200
+ },
201
+ };
202
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Git Sync Hooks
3
+ *
4
+ * When the live file watcher is disabled (e.g. on WSL2 `/mnt/*` drives,
5
+ * see watch-policy.ts), the SpecShip index would otherwise go stale until
6
+ * the user runs `specship sync` by hand. As an opt-in alternative, we can
7
+ * install git hooks that refresh the index after the operations that change
8
+ * files on disk: commit, merge (covers `git pull`), and checkout.
9
+ *
10
+ * The hooks run `specship sync` in the background so they never block git,
11
+ * and are guarded by `command -v specship` so they no-op cleanly when the
12
+ * CLI isn't on PATH. Our snippet is delimited by marker comments so install
13
+ * is idempotent and removal preserves any user-authored hook content.
14
+ */
15
+ export type GitHookName = 'post-commit' | 'post-merge' | 'post-checkout';
16
+ /** Hooks installed by default: commit, merge (git pull), and checkout. */
17
+ export declare const DEFAULT_SYNC_HOOKS: GitHookName[];
18
+ export interface GitHookResult {
19
+ /** Hook names that were created or updated. */
20
+ installed: GitHookName[];
21
+ /** Resolved hooks directory, or null when not a git repo. */
22
+ hooksDir: string | null;
23
+ /** Reason nothing happened (e.g. not a git repository). */
24
+ skipped?: string;
25
+ }
26
+ /**
27
+ * Whether `projectRoot` is inside a git working tree. Returns false if git
28
+ * isn't installed or the path isn't a repo.
29
+ */
30
+ export declare function isGitRepo(projectRoot: string): boolean;
31
+ /**
32
+ * Install (or update) the SpecShip sync hooks in a git repository.
33
+ * Idempotent: re-running replaces our marker block rather than duplicating
34
+ * it, and any user-authored hook content is preserved.
35
+ */
36
+ export declare function installGitSyncHook(projectRoot: string, hooks?: GitHookName[]): GitHookResult;
37
+ /**
38
+ * Remove the SpecShip sync hooks. Strips only our marker block; deletes the
39
+ * hook file entirely when nothing but a shebang remains, otherwise rewrites
40
+ * the user's content untouched.
41
+ */
42
+ export declare function removeGitSyncHook(projectRoot: string, hooks?: GitHookName[]): GitHookResult;
43
+ /** Whether any SpecShip sync hook is currently installed. */
44
+ export declare function isSyncHookInstalled(projectRoot: string, hooks?: GitHookName[]): boolean;
45
+ //# sourceMappingURL=git-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-hooks.d.ts","sourceRoot":"","sources":["../../src/sync/git-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,YAAY,GAAG,eAAe,CAAC;AAEzE,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,EAAE,WAAW,EAAmD,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAYtD;AAiED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,WAAW,EAAuB,GACxC,aAAa,CAmCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,WAAW,EAAuB,GACxC,aAAa,CA0Bf;AAED,6DAA6D;AAC7D,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,WAAW,EAAuB,GACxC,OAAO,CAOT"}