@selvakumaresra/specship 0.1.3 → 0.4.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 (718) hide show
  1. package/README.md +2 -2
  2. package/commands/ss-design-implement.md +84 -0
  3. package/commands/ss-design-loop.md +125 -0
  4. package/commands/{cg-drifted.md → ss-drifted.md} +2 -2
  5. package/commands/{cg-fix.md → ss-fix.md} +1 -1
  6. package/commands/{cg-implement.md → ss-implement.md} +1 -1
  7. package/commands/ss-spec-author.md +43 -0
  8. package/commands/ss-spec-review.md +48 -0
  9. package/dist/bin/node-version-check.d.ts +37 -0
  10. package/dist/bin/node-version-check.d.ts.map +1 -0
  11. package/dist/bin/node-version-check.js +79 -0
  12. package/dist/bin/node-version-check.js.map +1 -0
  13. package/dist/bin/specship.d.ts +25 -0
  14. package/dist/bin/specship.d.ts.map +1 -0
  15. package/dist/bin/specship.js +2085 -0
  16. package/dist/bin/specship.js.map +1 -0
  17. package/dist/bin/uninstall.d.ts +13 -0
  18. package/dist/bin/uninstall.d.ts.map +1 -0
  19. package/dist/bin/uninstall.js +35 -0
  20. package/dist/bin/uninstall.js.map +1 -0
  21. package/dist/context/formatter.d.ts +30 -0
  22. package/dist/context/formatter.d.ts.map +1 -0
  23. package/dist/context/formatter.js +263 -0
  24. package/dist/context/formatter.js.map +1 -0
  25. package/dist/context/index.d.ts +119 -0
  26. package/dist/context/index.d.ts.map +1 -0
  27. package/dist/context/index.js +1289 -0
  28. package/dist/context/index.js.map +1 -0
  29. package/dist/context/markers.d.ts +19 -0
  30. package/dist/context/markers.d.ts.map +1 -0
  31. package/dist/context/markers.js +22 -0
  32. package/dist/context/markers.js.map +1 -0
  33. package/dist/db/index.d.ts +103 -0
  34. package/dist/db/index.d.ts.map +1 -0
  35. package/dist/db/index.js +279 -0
  36. package/dist/db/index.js.map +1 -0
  37. package/dist/db/migrations.d.ts +44 -0
  38. package/dist/db/migrations.d.ts.map +1 -0
  39. package/dist/db/migrations.js +462 -0
  40. package/dist/db/migrations.js.map +1 -0
  41. package/dist/db/queries.d.ts +357 -0
  42. package/dist/db/queries.d.ts.map +1 -0
  43. package/dist/db/queries.js +1504 -0
  44. package/dist/db/queries.js.map +1 -0
  45. package/dist/db/schema.sql +419 -0
  46. package/dist/db/spec-queries.d.ts +101 -0
  47. package/dist/db/spec-queries.d.ts.map +1 -0
  48. package/dist/db/spec-queries.js +675 -0
  49. package/dist/db/spec-queries.js.map +1 -0
  50. package/dist/db/sqlite-adapter.d.ts +65 -0
  51. package/dist/db/sqlite-adapter.d.ts.map +1 -0
  52. package/dist/db/sqlite-adapter.js +214 -0
  53. package/dist/db/sqlite-adapter.js.map +1 -0
  54. package/dist/designer/artifact-store.js +54 -0
  55. package/dist/designer/browser.js +141 -0
  56. package/dist/designer/cdp-ensure.js +60 -0
  57. package/dist/designer/cdp-env.js +18 -0
  58. package/dist/designer/cdp-trace.js +599 -0
  59. package/dist/designer/cross-platform.js +74 -0
  60. package/dist/designer/designer-controller.js +1413 -0
  61. package/dist/designer/file-panel.js +39 -0
  62. package/dist/designer/interstitials.js +97 -0
  63. package/dist/designer/oopif-reader.js +176 -0
  64. package/dist/designer/package-meta.js +18 -0
  65. package/dist/designer/preview-host.js +50 -0
  66. package/dist/designer/repo-root.js +31 -0
  67. package/dist/designer/run-state.js +353 -0
  68. package/dist/designer/session-store.js +59 -0
  69. package/dist/designer/ui-anchors.js +651 -0
  70. package/dist/directory.d.ts +67 -0
  71. package/dist/directory.d.ts.map +1 -0
  72. package/dist/directory.js +267 -0
  73. package/dist/directory.js.map +1 -0
  74. package/dist/errors.d.ts +136 -0
  75. package/dist/errors.d.ts.map +1 -0
  76. package/dist/errors.js +219 -0
  77. package/dist/errors.js.map +1 -0
  78. package/dist/extraction/dfm-extractor.d.ts +31 -0
  79. package/dist/extraction/dfm-extractor.d.ts.map +1 -0
  80. package/dist/extraction/dfm-extractor.js +151 -0
  81. package/dist/extraction/dfm-extractor.js.map +1 -0
  82. package/dist/extraction/generated-detection.d.ts +30 -0
  83. package/dist/extraction/generated-detection.d.ts.map +1 -0
  84. package/dist/extraction/generated-detection.js +80 -0
  85. package/dist/extraction/generated-detection.js.map +1 -0
  86. package/dist/extraction/grammars.d.ts +100 -0
  87. package/dist/extraction/grammars.d.ts.map +1 -0
  88. package/dist/extraction/grammars.js +426 -0
  89. package/dist/extraction/grammars.js.map +1 -0
  90. package/dist/extraction/index.d.ts +138 -0
  91. package/dist/extraction/index.d.ts.map +1 -0
  92. package/dist/extraction/index.js +1394 -0
  93. package/dist/extraction/index.js.map +1 -0
  94. package/dist/extraction/languages/c-cpp.d.ts +4 -0
  95. package/dist/extraction/languages/c-cpp.d.ts.map +1 -0
  96. package/dist/extraction/languages/c-cpp.js +171 -0
  97. package/dist/extraction/languages/c-cpp.js.map +1 -0
  98. package/dist/extraction/languages/csharp.d.ts +3 -0
  99. package/dist/extraction/languages/csharp.d.ts.map +1 -0
  100. package/dist/extraction/languages/csharp.js +73 -0
  101. package/dist/extraction/languages/csharp.js.map +1 -0
  102. package/dist/extraction/languages/dart.d.ts +3 -0
  103. package/dist/extraction/languages/dart.d.ts.map +1 -0
  104. package/dist/extraction/languages/dart.js +192 -0
  105. package/dist/extraction/languages/dart.js.map +1 -0
  106. package/dist/extraction/languages/go.d.ts +3 -0
  107. package/dist/extraction/languages/go.d.ts.map +1 -0
  108. package/dist/extraction/languages/go.js +74 -0
  109. package/dist/extraction/languages/go.js.map +1 -0
  110. package/dist/extraction/languages/index.d.ts +10 -0
  111. package/dist/extraction/languages/index.d.ts.map +1 -0
  112. package/dist/extraction/languages/index.js +51 -0
  113. package/dist/extraction/languages/index.js.map +1 -0
  114. package/dist/extraction/languages/java.d.ts +3 -0
  115. package/dist/extraction/languages/java.d.ts.map +1 -0
  116. package/dist/extraction/languages/java.js +70 -0
  117. package/dist/extraction/languages/java.js.map +1 -0
  118. package/dist/extraction/languages/javascript.d.ts +3 -0
  119. package/dist/extraction/languages/javascript.d.ts.map +1 -0
  120. package/dist/extraction/languages/javascript.js +90 -0
  121. package/dist/extraction/languages/javascript.js.map +1 -0
  122. package/dist/extraction/languages/kotlin.d.ts +3 -0
  123. package/dist/extraction/languages/kotlin.d.ts.map +1 -0
  124. package/dist/extraction/languages/kotlin.js +259 -0
  125. package/dist/extraction/languages/kotlin.js.map +1 -0
  126. package/dist/extraction/languages/lua.d.ts +3 -0
  127. package/dist/extraction/languages/lua.d.ts.map +1 -0
  128. package/dist/extraction/languages/lua.js +150 -0
  129. package/dist/extraction/languages/lua.js.map +1 -0
  130. package/dist/extraction/languages/luau.d.ts +3 -0
  131. package/dist/extraction/languages/luau.d.ts.map +1 -0
  132. package/dist/extraction/languages/luau.js +37 -0
  133. package/dist/extraction/languages/luau.js.map +1 -0
  134. package/dist/extraction/languages/objc.d.ts +3 -0
  135. package/dist/extraction/languages/objc.d.ts.map +1 -0
  136. package/dist/extraction/languages/objc.js +133 -0
  137. package/dist/extraction/languages/objc.js.map +1 -0
  138. package/dist/extraction/languages/pascal.d.ts +3 -0
  139. package/dist/extraction/languages/pascal.d.ts.map +1 -0
  140. package/dist/extraction/languages/pascal.js +66 -0
  141. package/dist/extraction/languages/pascal.js.map +1 -0
  142. package/dist/extraction/languages/php.d.ts +3 -0
  143. package/dist/extraction/languages/php.d.ts.map +1 -0
  144. package/dist/extraction/languages/php.js +107 -0
  145. package/dist/extraction/languages/php.js.map +1 -0
  146. package/dist/extraction/languages/python.d.ts +3 -0
  147. package/dist/extraction/languages/python.d.ts.map +1 -0
  148. package/dist/extraction/languages/python.js +56 -0
  149. package/dist/extraction/languages/python.js.map +1 -0
  150. package/dist/extraction/languages/ruby.d.ts +3 -0
  151. package/dist/extraction/languages/ruby.d.ts.map +1 -0
  152. package/dist/extraction/languages/ruby.js +114 -0
  153. package/dist/extraction/languages/ruby.js.map +1 -0
  154. package/dist/extraction/languages/rust.d.ts +3 -0
  155. package/dist/extraction/languages/rust.d.ts.map +1 -0
  156. package/dist/extraction/languages/rust.js +109 -0
  157. package/dist/extraction/languages/rust.js.map +1 -0
  158. package/dist/extraction/languages/scala.d.ts +3 -0
  159. package/dist/extraction/languages/scala.d.ts.map +1 -0
  160. package/dist/extraction/languages/scala.js +139 -0
  161. package/dist/extraction/languages/scala.js.map +1 -0
  162. package/dist/extraction/languages/swift.d.ts +3 -0
  163. package/dist/extraction/languages/swift.d.ts.map +1 -0
  164. package/dist/extraction/languages/swift.js +91 -0
  165. package/dist/extraction/languages/swift.js.map +1 -0
  166. package/dist/extraction/languages/typescript.d.ts +3 -0
  167. package/dist/extraction/languages/typescript.d.ts.map +1 -0
  168. package/dist/extraction/languages/typescript.js +129 -0
  169. package/dist/extraction/languages/typescript.js.map +1 -0
  170. package/dist/extraction/liquid-extractor.d.ts +52 -0
  171. package/dist/extraction/liquid-extractor.d.ts.map +1 -0
  172. package/dist/extraction/liquid-extractor.js +313 -0
  173. package/dist/extraction/liquid-extractor.js.map +1 -0
  174. package/dist/extraction/mybatis-extractor.d.ts +48 -0
  175. package/dist/extraction/mybatis-extractor.d.ts.map +1 -0
  176. package/dist/extraction/mybatis-extractor.js +198 -0
  177. package/dist/extraction/mybatis-extractor.js.map +1 -0
  178. package/dist/extraction/parse-worker.d.ts +8 -0
  179. package/dist/extraction/parse-worker.d.ts.map +1 -0
  180. package/dist/extraction/parse-worker.js +94 -0
  181. package/dist/extraction/parse-worker.js.map +1 -0
  182. package/dist/extraction/specs/markdown-spec-extractor.d.ts +59 -0
  183. package/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -0
  184. package/dist/extraction/specs/markdown-spec-extractor.js +327 -0
  185. package/dist/extraction/specs/markdown-spec-extractor.js.map +1 -0
  186. package/dist/extraction/specs/types.d.ts +39 -0
  187. package/dist/extraction/specs/types.d.ts.map +1 -0
  188. package/dist/extraction/specs/types.js +8 -0
  189. package/dist/extraction/specs/types.js.map +1 -0
  190. package/dist/extraction/svelte-extractor.d.ts +56 -0
  191. package/dist/extraction/svelte-extractor.d.ts.map +1 -0
  192. package/dist/extraction/svelte-extractor.js +272 -0
  193. package/dist/extraction/svelte-extractor.js.map +1 -0
  194. package/dist/extraction/tree-sitter-helpers.d.ts +28 -0
  195. package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -0
  196. package/dist/extraction/tree-sitter-helpers.js +103 -0
  197. package/dist/extraction/tree-sitter-helpers.js.map +1 -0
  198. package/dist/extraction/tree-sitter-types.d.ts +193 -0
  199. package/dist/extraction/tree-sitter-types.d.ts.map +1 -0
  200. package/dist/extraction/tree-sitter-types.js +10 -0
  201. package/dist/extraction/tree-sitter-types.js.map +1 -0
  202. package/dist/extraction/tree-sitter.d.ts +317 -0
  203. package/dist/extraction/tree-sitter.d.ts.map +1 -0
  204. package/dist/extraction/tree-sitter.js +3092 -0
  205. package/dist/extraction/tree-sitter.js.map +1 -0
  206. package/dist/extraction/vue-extractor.d.ts +51 -0
  207. package/dist/extraction/vue-extractor.d.ts.map +1 -0
  208. package/dist/extraction/vue-extractor.js +251 -0
  209. package/dist/extraction/vue-extractor.js.map +1 -0
  210. package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
  211. package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
  212. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  213. package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
  214. package/dist/extraction/wasm-runtime-flags.d.ts +38 -0
  215. package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -0
  216. package/dist/extraction/wasm-runtime-flags.js +106 -0
  217. package/dist/extraction/wasm-runtime-flags.js.map +1 -0
  218. package/dist/graph/index.d.ts +8 -0
  219. package/dist/graph/index.d.ts.map +1 -0
  220. package/dist/graph/index.js +13 -0
  221. package/dist/graph/index.js.map +1 -0
  222. package/dist/graph/queries.d.ts +106 -0
  223. package/dist/graph/queries.d.ts.map +1 -0
  224. package/dist/graph/queries.js +366 -0
  225. package/dist/graph/queries.js.map +1 -0
  226. package/dist/graph/traversal.d.ts +127 -0
  227. package/dist/graph/traversal.d.ts.map +1 -0
  228. package/dist/graph/traversal.js +531 -0
  229. package/dist/graph/traversal.js.map +1 -0
  230. package/dist/index.d.ts +551 -0
  231. package/dist/index.d.ts.map +1 -0
  232. package/dist/index.js +1165 -0
  233. package/dist/index.js.map +1 -0
  234. package/dist/installer/config-writer.d.ts +28 -0
  235. package/dist/installer/config-writer.d.ts.map +1 -0
  236. package/dist/installer/config-writer.js +91 -0
  237. package/dist/installer/config-writer.js.map +1 -0
  238. package/dist/installer/index.d.ts +92 -0
  239. package/dist/installer/index.d.ts.map +1 -0
  240. package/dist/installer/index.js +416 -0
  241. package/dist/installer/index.js.map +1 -0
  242. package/dist/installer/instructions-template.d.ts +35 -0
  243. package/dist/installer/instructions-template.d.ts.map +1 -0
  244. package/dist/installer/instructions-template.js +51 -0
  245. package/dist/installer/instructions-template.js.map +1 -0
  246. package/dist/installer/targets/claude.d.ts +117 -0
  247. package/dist/installer/targets/claude.d.ts.map +1 -0
  248. package/dist/installer/targets/claude.js +736 -0
  249. package/dist/installer/targets/claude.js.map +1 -0
  250. package/dist/installer/targets/registry.d.ts +19 -0
  251. package/dist/installer/targets/registry.d.ts.map +1 -0
  252. package/dist/installer/targets/registry.js +31 -0
  253. package/dist/installer/targets/registry.js.map +1 -0
  254. package/dist/installer/targets/shared.d.ts +76 -0
  255. package/dist/installer/targets/shared.d.ts.map +1 -0
  256. package/dist/installer/targets/shared.js +256 -0
  257. package/dist/installer/targets/shared.js.map +1 -0
  258. package/dist/installer/targets/types.d.ts +84 -0
  259. package/dist/installer/targets/types.d.ts.map +1 -0
  260. package/dist/installer/targets/types.js +12 -0
  261. package/dist/installer/targets/types.js.map +1 -0
  262. package/dist/isolation/worktree.d.ts +65 -0
  263. package/dist/isolation/worktree.d.ts.map +1 -0
  264. package/dist/isolation/worktree.js +231 -0
  265. package/dist/isolation/worktree.js.map +1 -0
  266. package/dist/mcp/daemon-paths.d.ts +46 -0
  267. package/dist/mcp/daemon-paths.d.ts.map +1 -0
  268. package/dist/mcp/daemon-paths.js +125 -0
  269. package/dist/mcp/daemon-paths.js.map +1 -0
  270. package/dist/mcp/daemon.d.ts +161 -0
  271. package/dist/mcp/daemon.d.ts.map +1 -0
  272. package/dist/mcp/daemon.js +403 -0
  273. package/dist/mcp/daemon.js.map +1 -0
  274. package/dist/mcp/designer-tools.d.ts +33 -0
  275. package/dist/mcp/designer-tools.d.ts.map +1 -0
  276. package/dist/mcp/designer-tools.js +313 -0
  277. package/dist/mcp/designer-tools.js.map +1 -0
  278. package/dist/mcp/engine.d.ts +105 -0
  279. package/dist/mcp/engine.d.ts.map +1 -0
  280. package/dist/mcp/engine.js +270 -0
  281. package/dist/mcp/engine.js.map +1 -0
  282. package/dist/mcp/index.d.ts +112 -0
  283. package/dist/mcp/index.d.ts.map +1 -0
  284. package/dist/mcp/index.js +477 -0
  285. package/dist/mcp/index.js.map +1 -0
  286. package/dist/mcp/proxy.d.ts +81 -0
  287. package/dist/mcp/proxy.d.ts.map +1 -0
  288. package/dist/mcp/proxy.js +510 -0
  289. package/dist/mcp/proxy.js.map +1 -0
  290. package/dist/mcp/server-instructions.d.ts +18 -0
  291. package/dist/mcp/server-instructions.d.ts.map +1 -0
  292. package/dist/mcp/server-instructions.js +77 -0
  293. package/dist/mcp/server-instructions.js.map +1 -0
  294. package/dist/mcp/session.d.ts +77 -0
  295. package/dist/mcp/session.d.ts.map +1 -0
  296. package/dist/mcp/session.js +294 -0
  297. package/dist/mcp/session.js.map +1 -0
  298. package/dist/mcp/spec-tools.d.ts +39 -0
  299. package/dist/mcp/spec-tools.d.ts.map +1 -0
  300. package/dist/mcp/spec-tools.js +326 -0
  301. package/dist/mcp/spec-tools.js.map +1 -0
  302. package/dist/mcp/tools.d.ts +404 -0
  303. package/dist/mcp/tools.d.ts.map +1 -0
  304. package/dist/mcp/tools.js +3087 -0
  305. package/dist/mcp/tools.js.map +1 -0
  306. package/dist/mcp/transport.d.ts +188 -0
  307. package/dist/mcp/transport.d.ts.map +1 -0
  308. package/dist/mcp/transport.js +343 -0
  309. package/dist/mcp/transport.js.map +1 -0
  310. package/dist/mcp/version.d.ts +19 -0
  311. package/dist/mcp/version.d.ts.map +1 -0
  312. package/dist/mcp/version.js +71 -0
  313. package/dist/mcp/version.js.map +1 -0
  314. package/dist/resolution/callback-synthesizer.d.ts +10 -0
  315. package/dist/resolution/callback-synthesizer.d.ts.map +1 -0
  316. package/dist/resolution/callback-synthesizer.js +1300 -0
  317. package/dist/resolution/callback-synthesizer.js.map +1 -0
  318. package/dist/resolution/frameworks/cargo-workspace.d.ts +18 -0
  319. package/dist/resolution/frameworks/cargo-workspace.d.ts.map +1 -0
  320. package/dist/resolution/frameworks/cargo-workspace.js +225 -0
  321. package/dist/resolution/frameworks/cargo-workspace.js.map +1 -0
  322. package/dist/resolution/frameworks/csharp.d.ts +8 -0
  323. package/dist/resolution/frameworks/csharp.d.ts.map +1 -0
  324. package/dist/resolution/frameworks/csharp.js +241 -0
  325. package/dist/resolution/frameworks/csharp.js.map +1 -0
  326. package/dist/resolution/frameworks/drupal.d.ts +51 -0
  327. package/dist/resolution/frameworks/drupal.d.ts.map +1 -0
  328. package/dist/resolution/frameworks/drupal.js +367 -0
  329. package/dist/resolution/frameworks/drupal.js.map +1 -0
  330. package/dist/resolution/frameworks/expo-modules.d.ts +3 -0
  331. package/dist/resolution/frameworks/expo-modules.d.ts.map +1 -0
  332. package/dist/resolution/frameworks/expo-modules.js +143 -0
  333. package/dist/resolution/frameworks/expo-modules.js.map +1 -0
  334. package/dist/resolution/frameworks/express.d.ts +8 -0
  335. package/dist/resolution/frameworks/express.d.ts.map +1 -0
  336. package/dist/resolution/frameworks/express.js +308 -0
  337. package/dist/resolution/frameworks/express.js.map +1 -0
  338. package/dist/resolution/frameworks/fabric.d.ts +3 -0
  339. package/dist/resolution/frameworks/fabric.d.ts.map +1 -0
  340. package/dist/resolution/frameworks/fabric.js +354 -0
  341. package/dist/resolution/frameworks/fabric.js.map +1 -0
  342. package/dist/resolution/frameworks/go.d.ts +8 -0
  343. package/dist/resolution/frameworks/go.d.ts.map +1 -0
  344. package/dist/resolution/frameworks/go.js +161 -0
  345. package/dist/resolution/frameworks/go.js.map +1 -0
  346. package/dist/resolution/frameworks/index.d.ts +48 -0
  347. package/dist/resolution/frameworks/index.d.ts.map +1 -0
  348. package/dist/resolution/frameworks/index.js +161 -0
  349. package/dist/resolution/frameworks/index.js.map +1 -0
  350. package/dist/resolution/frameworks/java.d.ts +8 -0
  351. package/dist/resolution/frameworks/java.d.ts.map +1 -0
  352. package/dist/resolution/frameworks/java.js +504 -0
  353. package/dist/resolution/frameworks/java.js.map +1 -0
  354. package/dist/resolution/frameworks/laravel.d.ts +13 -0
  355. package/dist/resolution/frameworks/laravel.d.ts.map +1 -0
  356. package/dist/resolution/frameworks/laravel.js +257 -0
  357. package/dist/resolution/frameworks/laravel.js.map +1 -0
  358. package/dist/resolution/frameworks/nestjs.d.ts +26 -0
  359. package/dist/resolution/frameworks/nestjs.d.ts.map +1 -0
  360. package/dist/resolution/frameworks/nestjs.js +698 -0
  361. package/dist/resolution/frameworks/nestjs.js.map +1 -0
  362. package/dist/resolution/frameworks/play.d.ts +19 -0
  363. package/dist/resolution/frameworks/play.d.ts.map +1 -0
  364. package/dist/resolution/frameworks/play.js +111 -0
  365. package/dist/resolution/frameworks/play.js.map +1 -0
  366. package/dist/resolution/frameworks/python.d.ts +10 -0
  367. package/dist/resolution/frameworks/python.d.ts.map +1 -0
  368. package/dist/resolution/frameworks/python.js +396 -0
  369. package/dist/resolution/frameworks/python.js.map +1 -0
  370. package/dist/resolution/frameworks/react-native.d.ts +3 -0
  371. package/dist/resolution/frameworks/react-native.d.ts.map +1 -0
  372. package/dist/resolution/frameworks/react-native.js +360 -0
  373. package/dist/resolution/frameworks/react-native.js.map +1 -0
  374. package/dist/resolution/frameworks/react.d.ts +8 -0
  375. package/dist/resolution/frameworks/react.d.ts.map +1 -0
  376. package/dist/resolution/frameworks/react.js +365 -0
  377. package/dist/resolution/frameworks/react.js.map +1 -0
  378. package/dist/resolution/frameworks/ruby.d.ts +8 -0
  379. package/dist/resolution/frameworks/ruby.d.ts.map +1 -0
  380. package/dist/resolution/frameworks/ruby.js +302 -0
  381. package/dist/resolution/frameworks/ruby.js.map +1 -0
  382. package/dist/resolution/frameworks/rust.d.ts +8 -0
  383. package/dist/resolution/frameworks/rust.d.ts.map +1 -0
  384. package/dist/resolution/frameworks/rust.js +304 -0
  385. package/dist/resolution/frameworks/rust.js.map +1 -0
  386. package/dist/resolution/frameworks/svelte.d.ts +9 -0
  387. package/dist/resolution/frameworks/svelte.d.ts.map +1 -0
  388. package/dist/resolution/frameworks/svelte.js +249 -0
  389. package/dist/resolution/frameworks/svelte.js.map +1 -0
  390. package/dist/resolution/frameworks/swift-objc.d.ts +37 -0
  391. package/dist/resolution/frameworks/swift-objc.d.ts.map +1 -0
  392. package/dist/resolution/frameworks/swift-objc.js +252 -0
  393. package/dist/resolution/frameworks/swift-objc.js.map +1 -0
  394. package/dist/resolution/frameworks/swift.d.ts +10 -0
  395. package/dist/resolution/frameworks/swift.d.ts.map +1 -0
  396. package/dist/resolution/frameworks/swift.js +400 -0
  397. package/dist/resolution/frameworks/swift.js.map +1 -0
  398. package/dist/resolution/frameworks/vue.d.ts +9 -0
  399. package/dist/resolution/frameworks/vue.d.ts.map +1 -0
  400. package/dist/resolution/frameworks/vue.js +306 -0
  401. package/dist/resolution/frameworks/vue.js.map +1 -0
  402. package/dist/resolution/go-module.d.ts +26 -0
  403. package/dist/resolution/go-module.d.ts.map +1 -0
  404. package/dist/resolution/go-module.js +78 -0
  405. package/dist/resolution/go-module.js.map +1 -0
  406. package/dist/resolution/import-resolver.d.ts +68 -0
  407. package/dist/resolution/import-resolver.d.ts.map +1 -0
  408. package/dist/resolution/import-resolver.js +1275 -0
  409. package/dist/resolution/import-resolver.js.map +1 -0
  410. package/dist/resolution/index.d.ts +117 -0
  411. package/dist/resolution/index.d.ts.map +1 -0
  412. package/dist/resolution/index.js +895 -0
  413. package/dist/resolution/index.js.map +1 -0
  414. package/dist/resolution/lru-cache.d.ts +24 -0
  415. package/dist/resolution/lru-cache.d.ts.map +1 -0
  416. package/dist/resolution/lru-cache.js +62 -0
  417. package/dist/resolution/lru-cache.js.map +1 -0
  418. package/dist/resolution/name-matcher.d.ts +32 -0
  419. package/dist/resolution/name-matcher.d.ts.map +1 -0
  420. package/dist/resolution/name-matcher.js +596 -0
  421. package/dist/resolution/name-matcher.js.map +1 -0
  422. package/dist/resolution/path-aliases.d.ts +68 -0
  423. package/dist/resolution/path-aliases.d.ts.map +1 -0
  424. package/dist/resolution/path-aliases.js +238 -0
  425. package/dist/resolution/path-aliases.js.map +1 -0
  426. package/dist/resolution/spec-link-resolver.d.ts +103 -0
  427. package/dist/resolution/spec-link-resolver.d.ts.map +1 -0
  428. package/dist/resolution/spec-link-resolver.js +259 -0
  429. package/dist/resolution/spec-link-resolver.js.map +1 -0
  430. package/dist/resolution/strip-comments.d.ts +27 -0
  431. package/dist/resolution/strip-comments.d.ts.map +1 -0
  432. package/dist/resolution/strip-comments.js +441 -0
  433. package/dist/resolution/strip-comments.js.map +1 -0
  434. package/dist/resolution/swift-objc-bridge.d.ts +134 -0
  435. package/dist/resolution/swift-objc-bridge.d.ts.map +1 -0
  436. package/dist/resolution/swift-objc-bridge.js +256 -0
  437. package/dist/resolution/swift-objc-bridge.js.map +1 -0
  438. package/dist/resolution/types.d.ts +216 -0
  439. package/dist/resolution/types.d.ts.map +1 -0
  440. package/dist/resolution/types.js +8 -0
  441. package/dist/resolution/types.js.map +1 -0
  442. package/dist/resolution/workspace-packages.d.ts +48 -0
  443. package/dist/resolution/workspace-packages.d.ts.map +1 -0
  444. package/dist/resolution/workspace-packages.js +208 -0
  445. package/dist/resolution/workspace-packages.js.map +1 -0
  446. package/dist/search/query-parser.d.ts +57 -0
  447. package/dist/search/query-parser.d.ts.map +1 -0
  448. package/dist/search/query-parser.js +177 -0
  449. package/dist/search/query-parser.js.map +1 -0
  450. package/dist/search/query-utils.d.ts +71 -0
  451. package/dist/search/query-utils.d.ts.map +1 -0
  452. package/dist/search/query-utils.js +380 -0
  453. package/dist/search/query-utils.js.map +1 -0
  454. package/dist/server/cli.js +152 -0
  455. package/dist/server/index.js +12 -0
  456. package/dist/server/ingest/index.js +18 -0
  457. package/dist/server/ingest/ingestor.js +506 -0
  458. package/dist/server/ingest/parser.js +104 -0
  459. package/dist/server/ingest/pricing.js +78 -0
  460. package/dist/server/ingest/types.js +9 -0
  461. package/dist/server/ingest/watcher.js +77 -0
  462. package/dist/server/package.json +3 -0
  463. package/dist/server/project-registry.js +101 -0
  464. package/dist/server/routes/claude.js +868 -0
  465. package/dist/server/routes/graph.js +211 -0
  466. package/dist/server/routes/memory.js +272 -0
  467. package/dist/server/routes/projects.js +197 -0
  468. package/dist/server/routes/spec.js +265 -0
  469. package/dist/server/routes/status.js +112 -0
  470. package/dist/server/routes/workflow.js +212 -0
  471. package/dist/server/server.js +206 -0
  472. package/dist/server/static-handler.js +87 -0
  473. package/dist/sync/git-hooks.d.ts +45 -0
  474. package/dist/sync/git-hooks.d.ts.map +1 -0
  475. package/dist/sync/git-hooks.js +225 -0
  476. package/dist/sync/git-hooks.js.map +1 -0
  477. package/dist/sync/index.d.ts +19 -0
  478. package/dist/sync/index.d.ts.map +1 -0
  479. package/dist/sync/index.js +35 -0
  480. package/dist/sync/index.js.map +1 -0
  481. package/dist/sync/watch-policy.d.ts +48 -0
  482. package/dist/sync/watch-policy.d.ts.map +1 -0
  483. package/dist/sync/watch-policy.js +124 -0
  484. package/dist/sync/watch-policy.js.map +1 -0
  485. package/dist/sync/watcher.d.ts +283 -0
  486. package/dist/sync/watcher.d.ts.map +1 -0
  487. package/dist/sync/watcher.js +606 -0
  488. package/dist/sync/watcher.js.map +1 -0
  489. package/dist/sync/worktree.d.ts +54 -0
  490. package/dist/sync/worktree.d.ts.map +1 -0
  491. package/dist/sync/worktree.js +137 -0
  492. package/dist/sync/worktree.js.map +1 -0
  493. package/dist/types.d.ts +623 -0
  494. package/dist/types.d.ts.map +1 -0
  495. package/dist/types.js +108 -0
  496. package/dist/types.js.map +1 -0
  497. package/dist/ui/glyphs.d.ts +42 -0
  498. package/dist/ui/glyphs.d.ts.map +1 -0
  499. package/dist/ui/glyphs.js +78 -0
  500. package/dist/ui/glyphs.js.map +1 -0
  501. package/dist/ui/shimmer-progress.d.ts +11 -0
  502. package/dist/ui/shimmer-progress.d.ts.map +1 -0
  503. package/dist/ui/shimmer-progress.js +90 -0
  504. package/dist/ui/shimmer-progress.js.map +1 -0
  505. package/dist/ui/shimmer-worker.d.ts +2 -0
  506. package/dist/ui/shimmer-worker.d.ts.map +1 -0
  507. package/dist/ui/shimmer-worker.js +118 -0
  508. package/dist/ui/shimmer-worker.js.map +1 -0
  509. package/dist/ui/types.d.ts +17 -0
  510. package/dist/ui/types.d.ts.map +1 -0
  511. package/dist/ui/types.js +3 -0
  512. package/dist/ui/types.js.map +1 -0
  513. package/dist/utils.d.ts +205 -0
  514. package/dist/utils.d.ts.map +1 -0
  515. package/dist/utils.js +549 -0
  516. package/dist/utils.js.map +1 -0
  517. package/dist/web/chunk-2AJCHB7P.js +1 -0
  518. package/dist/web/chunk-2CPLUFCH.js +2 -0
  519. package/dist/web/chunk-2GBEK2GM.js +1 -0
  520. package/dist/web/chunk-2I7L37NS.js +1 -0
  521. package/dist/web/chunk-2NAWAJB5.js +1 -0
  522. package/dist/web/chunk-2OJBIPE4.js +1 -0
  523. package/dist/web/chunk-2YUJNZ2Y.js +6 -0
  524. package/dist/web/chunk-3E2WB6D5.js +1 -0
  525. package/dist/web/chunk-3EBFYSCH.js +2 -0
  526. package/dist/web/chunk-3QCQ4BXS.js +1 -0
  527. package/dist/web/chunk-42XVAQ6I.js +1 -0
  528. package/dist/web/chunk-45QHGCB4.js +17 -0
  529. package/dist/web/chunk-4IMMPEYM.js +1 -0
  530. package/dist/web/chunk-4TJQJPCZ.js +1 -0
  531. package/dist/web/chunk-4WZIHTPC.js +1 -0
  532. package/dist/web/chunk-4YVSYOSD.js +1 -0
  533. package/dist/web/chunk-5BQIOYKW.js +1 -0
  534. package/dist/web/chunk-5HGWHUJA.js +1 -0
  535. package/dist/web/chunk-5Y244R4G.js +1 -0
  536. package/dist/web/chunk-6RRDPT5Z.js +1 -0
  537. package/dist/web/chunk-6VKB2ZWM.js +1 -0
  538. package/dist/web/chunk-7DMFVTU4.js +1 -0
  539. package/dist/web/chunk-7RNS77UP.js +1 -0
  540. package/dist/web/chunk-7SMPKVEP.js +1 -0
  541. package/dist/web/chunk-A5R3MJMO.js +1 -0
  542. package/dist/web/chunk-ASZ77FMZ.js +1 -0
  543. package/dist/web/chunk-AZJVTPLU.js +1 -0
  544. package/dist/web/chunk-B3YPFY6A.js +1 -0
  545. package/dist/web/chunk-BLBRMCN2.js +1 -0
  546. package/dist/web/chunk-BMIAXD2V.js +2 -0
  547. package/dist/web/chunk-BUXWEHIY.js +1 -0
  548. package/dist/web/chunk-BYZFQSM6.js +1 -0
  549. package/dist/web/chunk-D5OCNEJA.js +2 -0
  550. package/dist/web/chunk-DLQPZWSI.css +1 -0
  551. package/dist/web/chunk-DTRN7FZR.js +1 -0
  552. package/dist/web/chunk-DYRFLPJA.js +1 -0
  553. package/dist/web/chunk-E3J3CXR5.js +1 -0
  554. package/dist/web/chunk-E44X4RH2.js +1 -0
  555. package/dist/web/chunk-E73OX2P7.js +1 -0
  556. package/dist/web/chunk-EAXRKDLV.js +1 -0
  557. package/dist/web/chunk-EBKKDHYI.js +1 -0
  558. package/dist/web/chunk-EE7V7Q5P.js +1 -0
  559. package/dist/web/chunk-EKY2FUHU.js +1 -0
  560. package/dist/web/chunk-EMGMOEVR.js +1 -0
  561. package/dist/web/chunk-EP6XOPXH.js +1 -0
  562. package/dist/web/chunk-ESGDLJOJ.js +1 -0
  563. package/dist/web/chunk-ETJG7NCY.js +1 -0
  564. package/dist/web/chunk-EUUEFEDI.js +1 -0
  565. package/dist/web/chunk-FGNZDHTL.js +11 -0
  566. package/dist/web/chunk-FHZHD2ZG.js +1 -0
  567. package/dist/web/chunk-FIJW2UNJ.js +1 -0
  568. package/dist/web/chunk-FMV5PXRC.js +5 -0
  569. package/dist/web/chunk-G7VZT5KB.js +3 -0
  570. package/dist/web/chunk-GR72OOCN.js +1 -0
  571. package/dist/web/chunk-GRZYXPSO.js +7 -0
  572. package/dist/web/chunk-GWPVKJIY.js +1 -0
  573. package/dist/web/chunk-GYGPS3AN.js +1 -0
  574. package/dist/web/chunk-H7AF7YS4.js +1 -0
  575. package/dist/web/chunk-HDZDQILN.js +1 -0
  576. package/dist/web/chunk-HMK6UO6N.js +1 -0
  577. package/dist/web/chunk-HZA6NEAB.js +1 -0
  578. package/dist/web/chunk-IHEE5NYJ.js +1 -0
  579. package/dist/web/chunk-ISNEBICW.js +1 -0
  580. package/dist/web/chunk-J2GZVLHH.js +1 -0
  581. package/dist/web/chunk-JTFXTIPE.js +903 -0
  582. package/dist/web/chunk-L37MTFSG.js +3 -0
  583. package/dist/web/chunk-LB6JPLX2.js +1 -0
  584. package/dist/web/chunk-LNSVDHCI.js +1 -0
  585. package/dist/web/chunk-LVGIY3SO.js +1 -0
  586. package/dist/web/chunk-LXLHIHEN.js +1 -0
  587. package/dist/web/chunk-MC4DFIHG.js +1 -0
  588. package/dist/web/chunk-MVOMVPYB.js +1 -0
  589. package/dist/web/chunk-N6SS4G6S.js +1 -0
  590. package/dist/web/chunk-NTBJG6SJ.js +1 -0
  591. package/dist/web/chunk-NUDB3Q2Y.js +3 -0
  592. package/dist/web/chunk-NZEZCT65.js +1 -0
  593. package/dist/web/chunk-OXEF5E3E.js +1 -0
  594. package/dist/web/chunk-PDN6QYGJ.js +4 -0
  595. package/dist/web/chunk-PGGJPDJG.js +1 -0
  596. package/dist/web/chunk-PUYSJNJR.js +1 -0
  597. package/dist/web/chunk-Q2RVFS45.js +1 -0
  598. package/dist/web/chunk-Q7L6LLAK.js +1 -0
  599. package/dist/web/chunk-QCMKJIWY.js +1 -0
  600. package/dist/web/chunk-QH6CF3M3.js +1 -0
  601. package/dist/web/chunk-QQ5LD7PI.js +1 -0
  602. package/dist/web/chunk-QR6L3KAC.js +1 -0
  603. package/dist/web/chunk-R2DLK4HO.js +1 -0
  604. package/dist/web/chunk-R5W2MDZN.js +1 -0
  605. package/dist/web/chunk-RD6TVPOT.js +1 -0
  606. package/dist/web/chunk-RKY4EJYJ.js +1 -0
  607. package/dist/web/chunk-RONYWVY7.js +1 -0
  608. package/dist/web/chunk-RXKXYF2C.js +1 -0
  609. package/dist/web/chunk-SBWU7JFC.js +1 -0
  610. package/dist/web/chunk-SEXBRGYK.js +1 -0
  611. package/dist/web/chunk-SHPTC4RL.js +1 -0
  612. package/dist/web/chunk-SUZYBYDW.js +1 -0
  613. package/dist/web/chunk-SWKJRNYY.js +1 -0
  614. package/dist/web/chunk-T66XVKGB.js +1 -0
  615. package/dist/web/chunk-T7AZ65JP.js +1 -0
  616. package/dist/web/chunk-TCZDVOHD.js +1 -0
  617. package/dist/web/chunk-TPTITA3V.js +1 -0
  618. package/dist/web/chunk-TR335633.js +1 -0
  619. package/dist/web/chunk-UBOZGQNK.js +1 -0
  620. package/dist/web/chunk-UR5KDXPX.js +1 -0
  621. package/dist/web/chunk-UR6O2GEH.js +1 -0
  622. package/dist/web/chunk-UTNMGWTP.js +1 -0
  623. package/dist/web/chunk-UYC52MBC.js +1 -0
  624. package/dist/web/chunk-VECWMHJP.js +1 -0
  625. package/dist/web/chunk-VUACT35R.js +3 -0
  626. package/dist/web/chunk-VZI7H4SZ.js +1 -0
  627. package/dist/web/chunk-WAI2JMZP.js +1 -0
  628. package/dist/web/chunk-WB6YHOD4.js +1 -0
  629. package/dist/web/chunk-WBT64AWV.js +1 -0
  630. package/dist/web/chunk-WCKHQIYN.js +1 -0
  631. package/dist/web/chunk-WDU3WICG.js +1 -0
  632. package/dist/web/chunk-WFXJIXZE.js +4 -0
  633. package/dist/web/chunk-WLIMNDS3.js +1 -0
  634. package/dist/web/chunk-WTGYRH3Z.js +298 -0
  635. package/dist/web/chunk-WXTCVDTP.js +1 -0
  636. package/dist/web/chunk-X2HTISHL.js +1 -0
  637. package/dist/web/chunk-XCDHWLVH.js +1 -0
  638. package/dist/web/chunk-Y3H6FFUZ.js +1 -0
  639. package/dist/web/chunk-Y4F5ULGJ.js +1 -0
  640. package/dist/web/chunk-YAMRN47K.js +2 -0
  641. package/dist/web/chunk-YEGKAAEE.js +1 -0
  642. package/dist/web/chunk-YM2KU57F.js +1 -0
  643. package/dist/web/chunk-YRERBP6T.js +1 -0
  644. package/dist/web/chunk-ZLV4VCDG.js +3 -0
  645. package/dist/web/chunk-ZTVI5KFF.js +1 -0
  646. package/dist/web/favicon-16.png +0 -0
  647. package/dist/web/favicon-180.png +0 -0
  648. package/dist/web/favicon-32.png +0 -0
  649. package/dist/web/favicon-512.png +0 -0
  650. package/dist/web/favicon-small.svg +15 -0
  651. package/dist/web/favicon.ico +0 -0
  652. package/dist/web/favicon.svg +20 -0
  653. package/dist/web/index.html +145 -0
  654. package/dist/web/main-ESADRXN2.css +1 -0
  655. package/dist/web/main-R53HA54V.js +1 -0
  656. package/dist/web/media/codicon-LN6W7LCM.ttf +0 -0
  657. package/dist/web/styles-KSOPUVDA.css +1 -0
  658. package/dist/web/sw.js +69 -0
  659. package/dist/workflows/condition-evaluator.d.ts +75 -0
  660. package/dist/workflows/condition-evaluator.d.ts.map +1 -0
  661. package/dist/workflows/condition-evaluator.js +282 -0
  662. package/dist/workflows/condition-evaluator.js.map +1 -0
  663. package/dist/workflows/defaults/claude-design-implement.yaml +336 -0
  664. package/dist/workflows/defaults/index.d.ts +26 -0
  665. package/dist/workflows/defaults/index.d.ts.map +1 -0
  666. package/dist/workflows/defaults/index.js +94 -0
  667. package/dist/workflows/defaults/index.js.map +1 -0
  668. package/dist/workflows/defaults/spec-author.yaml +214 -0
  669. package/dist/workflows/defaults/spec-fix.yaml +110 -0
  670. package/dist/workflows/defaults/spec-implement.yaml +150 -0
  671. package/dist/workflows/defaults/spec-relink.yaml +81 -0
  672. package/dist/workflows/defaults/spec-verify.yaml +51 -0
  673. package/dist/workflows/discovery.d.ts +46 -0
  674. package/dist/workflows/discovery.d.ts.map +1 -0
  675. package/dist/workflows/discovery.js +193 -0
  676. package/dist/workflows/discovery.js.map +1 -0
  677. package/dist/workflows/executor.d.ts +83 -0
  678. package/dist/workflows/executor.d.ts.map +1 -0
  679. package/dist/workflows/executor.js +624 -0
  680. package/dist/workflows/executor.js.map +1 -0
  681. package/dist/workflows/runners/approval.d.ts +18 -0
  682. package/dist/workflows/runners/approval.d.ts.map +1 -0
  683. package/dist/workflows/runners/approval.js +34 -0
  684. package/dist/workflows/runners/approval.js.map +1 -0
  685. package/dist/workflows/runners/bash.d.ts +13 -0
  686. package/dist/workflows/runners/bash.d.ts.map +1 -0
  687. package/dist/workflows/runners/bash.js +143 -0
  688. package/dist/workflows/runners/bash.js.map +1 -0
  689. package/dist/workflows/runners/cancel.d.ts +10 -0
  690. package/dist/workflows/runners/cancel.d.ts.map +1 -0
  691. package/dist/workflows/runners/cancel.js +19 -0
  692. package/dist/workflows/runners/cancel.js.map +1 -0
  693. package/dist/workflows/runners/prompt.d.ts +28 -0
  694. package/dist/workflows/runners/prompt.d.ts.map +1 -0
  695. package/dist/workflows/runners/prompt.js +212 -0
  696. package/dist/workflows/runners/prompt.js.map +1 -0
  697. package/dist/workflows/runners/script.d.ts +17 -0
  698. package/dist/workflows/runners/script.d.ts.map +1 -0
  699. package/dist/workflows/runners/script.js +155 -0
  700. package/dist/workflows/runners/script.js.map +1 -0
  701. package/dist/workflows/runners/types.d.ts +51 -0
  702. package/dist/workflows/runners/types.d.ts.map +1 -0
  703. package/dist/workflows/runners/types.js +13 -0
  704. package/dist/workflows/runners/types.js.map +1 -0
  705. package/dist/workflows/schemas/workflow.d.ts +166 -0
  706. package/dist/workflows/schemas/workflow.d.ts.map +1 -0
  707. package/dist/workflows/schemas/workflow.js +437 -0
  708. package/dist/workflows/schemas/workflow.js.map +1 -0
  709. package/hooks/hooks.json +11 -0
  710. package/package.json +7 -3
  711. package/scripts/offline-install.sh +19 -6
  712. package/selectors.json +41 -0
  713. /package/commands/{cg-explore.md → ss-explore.md} +0 -0
  714. /package/commands/{cg-impact.md → ss-impact.md} +0 -0
  715. /package/commands/{cg-relink.md → ss-relink.md} +0 -0
  716. /package/commands/{cg-spec.md → ss-spec.md} +0 -0
  717. /package/commands/{cg-sync.md → ss-sync.md} +0 -0
  718. /package/commands/{cg-trace.md → ss-trace.md} +0 -0
@@ -0,0 +1,599 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CdpTraceRecorder = exports.CdpSession = void 0;
7
+ exports.scrubSecrets = scrubSecrets;
8
+ exports.asRec = asRec;
9
+ exports.redact = redact;
10
+ exports.listTargets = listTargets;
11
+ exports.findDesignTarget = findDesignTarget;
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const node_path_1 = __importDefault(require("node:path"));
14
+ const cdp_ensure_1 = require("./cdp-ensure");
15
+ // CDP network trace recorder — spike-grade groundwork for the future
16
+ // network-first run-state observer (RUNNING/FINISHED/STALLED/BLOCKED).
17
+ //
18
+ // Attaches a second CDP client directly to the design tab's page target
19
+ // (agent-browser keeps driving the page through its own client; CDP allows
20
+ // multiple simultaneous clients) and streams Network/Page events to JSONL.
21
+ //
22
+ // Uses the native global WebSocket (stable since Node 22.4). The package
23
+ // declares engines >=22 so runtime code can use it without a `ws` dependency.
24
+ //
25
+ // Known blind spot: the claudeusercontent.com preview iframe is an
26
+ // out-of-process frame — its document fetches never reach this page target's
27
+ // Network domain. Generation API traffic originates in the main frame, which
28
+ // is what we're here for. Upgrade path if traces show a gap:
29
+ // Target.setAutoAttach({flatten:true}) + per-session Network.enable; send()
30
+ // and event handling already tolerate a sessionId field for that reason.
31
+ const DEFAULT_PORT = process.env.DESIGNER_CDP || '9222';
32
+ const DESIGN_URL_PATTERN = /^https:\/\/claude\.ai\/design/;
33
+ const REDACT_KEY_PATTERN = /^(cookie|set-cookie|authorization|proxy-authorization|x-api-key)$/i;
34
+ const STREAMABLE_RESOURCE_TYPES = new Set(['XHR', 'Fetch', 'EventSource']);
35
+ // URLs whose request/response bodies we never capture — auth/session exchanges
36
+ // can carry credentials as plaintext JSON values that header-key redaction
37
+ // can't see. The generation traffic we care about (OmeletteService) is not here.
38
+ const AUTH_URL_DENYLIST = /\/(oauth|auth|login|logout|sign[_-]?in|sign[_-]?out|sign[_-]?up|register|token|sessions?|account|credential|password|mfa|totp|verify)\b/i;
39
+ // Value-level secret scrub for captured *bodies* (postData, response bodies, WS
40
+ // frame payloads). redact() only matches header *key names*; a token sitting in
41
+ // a JSON value or form field is a value blob it can't reach. Best-effort: catch
42
+ // the common token shapes before they hit disk. Exported for testability.
43
+ function scrubSecrets(s) {
44
+ return s
45
+ .replace(/eyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}/g, '[redacted-jwt]')
46
+ .replace(/\bsk-[A-Za-z0-9_-]{16,}\b/g, '[redacted-key]')
47
+ .replace(/(["']?(?:access[_-]?token|refresh[_-]?token|id[_-]?token|session[_-]?key|sessionKey|api[_-]?key|client[_-]?secret|secret|password|passwd|pwd)["']?\s*[:=]\s*["']?)[^"'&,;\s}]+/gi, '$1[redacted]')
48
+ .replace(/\bsessionKey=[^;"'\s&]+/gi, 'sessionKey=[redacted]')
49
+ .replace(/\b([Bb]earer)\s+[A-Za-z0-9._~+/=-]{12,}/g, '$1 [redacted]');
50
+ }
51
+ // Events persisted verbatim (post-redaction). Everything else — notably the
52
+ // Network.*ExtraInfo pair, which carries real Cookie/Set-Cookie headers — is
53
+ // only counted in droppedByMethod.
54
+ const PERSIST_METHODS = new Set([
55
+ 'Network.requestWillBeSent',
56
+ 'Network.responseReceived',
57
+ 'Network.dataReceived',
58
+ 'Network.loadingFinished',
59
+ 'Network.loadingFailed',
60
+ 'Network.requestServedFromCache',
61
+ 'Network.eventSourceMessageReceived',
62
+ 'Network.webSocketCreated',
63
+ 'Network.webSocketWillSendHandshakeRequest',
64
+ 'Network.webSocketHandshakeResponseReceived',
65
+ 'Network.webSocketFrameSent',
66
+ 'Network.webSocketFrameReceived',
67
+ 'Network.webSocketClosed',
68
+ 'Page.frameNavigated',
69
+ 'Page.frameStartedLoading',
70
+ 'Page.frameStoppedLoading',
71
+ 'Page.lifecycleEvent'
72
+ ]);
73
+ // Narrow an unknown CDP payload to a record before keyed access. Shared by the
74
+ // CDP subclasses (run-state, oopif-reader) that parse event/response shapes.
75
+ function asRec(v) {
76
+ return v && typeof v === 'object' && !Array.isArray(v) ? v : {};
77
+ }
78
+ function isCdpTarget(v) {
79
+ const r = asRec(v);
80
+ return (typeof r.id === 'string' &&
81
+ typeof r.type === 'string' &&
82
+ typeof r.title === 'string' &&
83
+ typeof r.url === 'string' &&
84
+ typeof r.webSocketDebuggerUrl === 'string');
85
+ }
86
+ /** Deep-walk redaction of sensitive header keys. Exported for testability. */
87
+ function redact(value) {
88
+ if (Array.isArray(value))
89
+ return value.map(redact);
90
+ if (value && typeof value === 'object') {
91
+ const out = {};
92
+ for (const [k, v] of Object.entries(value)) {
93
+ out[k] = REDACT_KEY_PATTERN.test(k) ? '[redacted]' : redact(v);
94
+ }
95
+ return out;
96
+ }
97
+ return value;
98
+ }
99
+ async function listTargets(port = DEFAULT_PORT) {
100
+ const res = await fetch(`http://127.0.0.1:${port}/json/list`, { signal: AbortSignal.timeout(3000) });
101
+ if (!res.ok)
102
+ throw new Error(`CDP /json/list on :${port} returned ${res.status}`);
103
+ const body = await res.json();
104
+ if (!Array.isArray(body))
105
+ throw new Error(`CDP /json/list on :${port} returned a non-array payload`);
106
+ return body.filter(isCdpTarget);
107
+ }
108
+ async function findDesignTarget({ port = DEFAULT_PORT, urlPattern = DESIGN_URL_PATTERN, preferUrlPrefix = null } = {}) {
109
+ const targets = await listTargets(port);
110
+ const candidates = targets.filter((t) => t.type === 'page' && urlPattern.test(t.url) && t.webSocketDebuggerUrl);
111
+ if (candidates.length === 0) {
112
+ throw new Error(`No page target matching ${urlPattern} on CDP :${port}. Open claude.ai/design first.`);
113
+ }
114
+ if (preferUrlPrefix) {
115
+ // Exact URL first: the home URL (https://claude.ai/design) is a *prefix* of
116
+ // every /design/p/<uuid> tab, so a startsWith match alone could bind to an
117
+ // arbitrary project tab instead of the exact tab the caller is on (#66).
118
+ const exactMatches = candidates.filter((t) => t.url === preferUrlPrefix);
119
+ const onlyExact = exactMatches[0];
120
+ if (exactMatches.length === 1 && onlyExact)
121
+ return onlyExact;
122
+ if (exactMatches.length > 1) {
123
+ // An exact URL match still isn't an exact TAB match: two tabs at the same
124
+ // URL (e.g. duplicate claude.ai/design home tabs) can't be told apart by
125
+ // URL, so fail rather than bind an arbitrary (possibly idle) one (#66).
126
+ // Callers that tolerate it (RunStateObserver.attach) degrade to null.
127
+ throw new Error(`Multiple tabs open at exactly ${preferUrlPrefix} — close the duplicate(s) so the right tab can be identified.`);
128
+ }
129
+ const preferred = candidates.find((t) => t.url.startsWith(preferUrlPrefix));
130
+ if (preferred)
131
+ return preferred;
132
+ }
133
+ const only = candidates[0];
134
+ if (candidates.length === 1 && only)
135
+ return only;
136
+ throw new Error(`Multiple design tabs match — pass --target-url to disambiguate:\n` +
137
+ candidates.map((t) => ` ${t.url}`).join('\n'));
138
+ }
139
+ class CdpSession {
140
+ ws;
141
+ target;
142
+ sessionOpts;
143
+ stopped = false;
144
+ reconnects = 0;
145
+ pending = new Map();
146
+ socketClosed = false;
147
+ nextId = 0;
148
+ constructor(ws, target, opts = {}) {
149
+ this.ws = ws;
150
+ this.target = target;
151
+ this.sessionOpts = {
152
+ port: opts.port ?? DEFAULT_PORT,
153
+ urlPattern: opts.urlPattern ?? DESIGN_URL_PATTERN,
154
+ preferUrlPrefix: opts.preferUrlPrefix ?? null,
155
+ reconnect: opts.reconnect ?? true
156
+ };
157
+ this.wire(ws);
158
+ }
159
+ static async connectTarget(opts = {}) {
160
+ await (0, cdp_ensure_1.ensureCdpUp)();
161
+ const target = await findDesignTarget({
162
+ port: opts.port ?? DEFAULT_PORT,
163
+ urlPattern: opts.urlPattern,
164
+ preferUrlPrefix: opts.preferUrlPrefix ?? null
165
+ });
166
+ const ws = await this.openSocket(target.webSocketDebuggerUrl);
167
+ return { ws, target };
168
+ }
169
+ static openSocket(url, timeoutMs = 5000) {
170
+ return new Promise((resolve, reject) => {
171
+ const ws = new WebSocket(url);
172
+ // A half-open WS (e.g. a wedged debug Chrome) would otherwise leave this
173
+ // pending forever — attach() never resolves/rejects, defeating callers'
174
+ // "degrade, don't hang" contract (#67 review). Bound the open and close the
175
+ // socket on timeout. Reject is handled by every caller (attach -> null /
176
+ // throw; the reconnect loop keeps polling).
177
+ const timer = setTimeout(() => {
178
+ cleanup();
179
+ try {
180
+ ws.close();
181
+ }
182
+ catch {
183
+ /* already closing */
184
+ }
185
+ reject(new Error(`CDP WebSocket open timed out after ${timeoutMs}ms: ${url}`));
186
+ }, timeoutMs);
187
+ const onOpen = () => {
188
+ cleanup();
189
+ resolve(ws);
190
+ };
191
+ const onError = () => {
192
+ cleanup();
193
+ reject(new Error(`Failed to open CDP WebSocket ${url}`));
194
+ };
195
+ const cleanup = () => {
196
+ clearTimeout(timer);
197
+ ws.removeEventListener('open', onOpen);
198
+ ws.removeEventListener('error', onError);
199
+ };
200
+ ws.addEventListener('open', onOpen);
201
+ ws.addEventListener('error', onError);
202
+ });
203
+ }
204
+ targetInfo() {
205
+ return { url: this.target.url, wsUrl: this.target.webSocketDebuggerUrl, port: this.sessionOpts.port };
206
+ }
207
+ async enableDomains() {
208
+ await this.send('Network.enable', { maxTotalBufferSize: 100_000_000, maxResourceBufferSize: 50_000_000 });
209
+ }
210
+ send(method, params, sessionId) {
211
+ const id = ++this.nextId;
212
+ const msg = { id, method };
213
+ if (params !== undefined)
214
+ msg.params = params;
215
+ if (sessionId)
216
+ msg.sessionId = sessionId;
217
+ return new Promise((resolve, reject) => {
218
+ this.pending.set(id, { resolve, reject });
219
+ try {
220
+ this.ws.send(JSON.stringify(msg));
221
+ }
222
+ catch (e) {
223
+ this.pending.delete(id);
224
+ reject(e instanceof Error ? e : new Error(String(e)));
225
+ }
226
+ });
227
+ }
228
+ close() {
229
+ this.closeSocket();
230
+ }
231
+ closeSocket() {
232
+ if (this.socketClosed)
233
+ return false;
234
+ this.socketClosed = true;
235
+ this.stopped = true;
236
+ this.rejectPending(new Error('CDP WebSocket closed'));
237
+ try {
238
+ this.ws.close();
239
+ }
240
+ catch {
241
+ /* already closed */
242
+ }
243
+ return true;
244
+ }
245
+ onSocketGap(_detail) { }
246
+ onSocketReconnected(_target) { }
247
+ onSocketReconnectFailed(_detail) { }
248
+ wire(ws) {
249
+ ws.addEventListener('message', (ev) => {
250
+ this.onMessage(typeof ev.data === 'string' ? ev.data : String(ev.data));
251
+ });
252
+ ws.addEventListener('close', () => {
253
+ void this.handleClose();
254
+ });
255
+ }
256
+ onMessage(raw) {
257
+ let msg;
258
+ try {
259
+ msg = JSON.parse(raw);
260
+ }
261
+ catch {
262
+ return;
263
+ }
264
+ if (!msg || typeof msg !== 'object' || Array.isArray(msg))
265
+ return;
266
+ const rec = msg;
267
+ if (typeof rec.id === 'number') {
268
+ const p = this.pending.get(rec.id);
269
+ if (!p)
270
+ return;
271
+ this.pending.delete(rec.id);
272
+ if (rec.error)
273
+ p.reject(new Error(`CDP ${JSON.stringify(rec.error)}`));
274
+ else
275
+ p.resolve(rec.result);
276
+ return;
277
+ }
278
+ const method = typeof rec.method === 'string' ? rec.method : '';
279
+ if (!method)
280
+ return;
281
+ this.onEvent(method, rec.params, typeof rec.sessionId === 'string' ? rec.sessionId : undefined);
282
+ }
283
+ rejectPending(error) {
284
+ for (const [, p] of this.pending)
285
+ p.reject(error);
286
+ this.pending.clear();
287
+ }
288
+ async handleClose() {
289
+ this.rejectPending(new Error('CDP WebSocket closed'));
290
+ if (this.stopped)
291
+ return;
292
+ this.onSocketGap({ reason: 'socket-closed' });
293
+ if (!this.sessionOpts.reconnect)
294
+ return;
295
+ for (let i = 0; i < 30 && !this.stopped; i++) {
296
+ await new Promise((r) => setTimeout(r, 1000));
297
+ try {
298
+ const target = await findDesignTarget({
299
+ port: this.sessionOpts.port,
300
+ urlPattern: this.sessionOpts.urlPattern,
301
+ preferUrlPrefix: this.sessionOpts.preferUrlPrefix
302
+ });
303
+ const ws = await CdpSession.openSocket(target.webSocketDebuggerUrl);
304
+ this.ws = ws;
305
+ this.target = target;
306
+ this.wire(ws);
307
+ await this.enableDomains();
308
+ this.reconnects++;
309
+ this.onSocketReconnected(target);
310
+ return;
311
+ }
312
+ catch {
313
+ // target not back yet — keep polling
314
+ }
315
+ }
316
+ if (!this.stopped)
317
+ this.onSocketReconnectFailed({ gaveUpAfterMs: 30_000 });
318
+ }
319
+ }
320
+ exports.CdpSession = CdpSession;
321
+ class CdpTraceRecorder extends CdpSession {
322
+ opts;
323
+ out;
324
+ requests = new Map();
325
+ wsSocketUrls = new Map();
326
+ pendingBodies = new Set();
327
+ startedAt = Date.now();
328
+ total = 0;
329
+ bodyCaptures = 0;
330
+ ended = false;
331
+ byMethod = {};
332
+ droppedByMethod = {};
333
+ constructor(ws, target, opts) {
334
+ super(ws, target, opts);
335
+ this.opts = {
336
+ outFile: opts.outFile,
337
+ port: opts.port ?? DEFAULT_PORT,
338
+ urlPattern: opts.urlPattern ?? DESIGN_URL_PATTERN,
339
+ preferUrlPrefix: opts.preferUrlPrefix ?? null,
340
+ captureBodiesFor: opts.captureBodiesFor ?? /^https:\/\/claude\.ai\//,
341
+ maxBodyBytesPerRequest: opts.maxBodyBytesPerRequest ?? 2 * 1024 * 1024,
342
+ reconnect: opts.reconnect ?? true
343
+ };
344
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(opts.outFile), { recursive: true });
345
+ this.out = node_fs_1.default.createWriteStream(opts.outFile, { flags: 'a' });
346
+ // Swallow stream errors (disk full, write-after-end races) — an unhandled
347
+ // 'error' event on the stream would otherwise crash the process.
348
+ this.out.on('error', () => { });
349
+ }
350
+ static async attach(opts) {
351
+ if (typeof WebSocket === 'undefined') {
352
+ throw new Error('Native WebSocket unavailable — cdp-trace requires Node >= 22.');
353
+ }
354
+ const { ws, target } = await CdpTraceRecorder.connectTarget(opts);
355
+ return new CdpTraceRecorder(ws, target, opts);
356
+ }
357
+ async start() {
358
+ this.startedAt = Date.now();
359
+ await this.enableDomains();
360
+ this.writeLine({
361
+ ts: Date.now(),
362
+ kind: 'recorder',
363
+ event: 'attach',
364
+ detail: { targetUrl: this.target.url, wsUrl: this.target.webSocketDebuggerUrl }
365
+ });
366
+ }
367
+ async enableDomains() {
368
+ await super.enableDomains();
369
+ await this.send('Page.enable');
370
+ await this.send('Page.setLifecycleEventsEnabled', { enabled: true });
371
+ }
372
+ marker(name, detail) {
373
+ this.writeLine({ ts: Date.now(), kind: 'recorder', event: 'marker', detail: { name, ...asRec(detail) } });
374
+ }
375
+ record(ev) {
376
+ this.writeLine({ ...ev, ts: ev.ts || Date.now() });
377
+ }
378
+ async stop() {
379
+ this.stopped = true;
380
+ // Give in-flight body fetches a moment to land, then move on.
381
+ await Promise.race([
382
+ Promise.allSettled([...this.pendingBodies]),
383
+ new Promise((r) => setTimeout(r, 3000))
384
+ ]);
385
+ this.writeLine({ ts: Date.now(), kind: 'recorder', event: 'detach' });
386
+ this.close();
387
+ // Mark ended before end() so any late body-fetch .catch (rejected by close())
388
+ // is a no-op in writeLine rather than a write-after-end stream error.
389
+ this.ended = true;
390
+ await new Promise((resolve) => this.out.end(resolve));
391
+ return {
392
+ durationMs: Date.now() - this.startedAt,
393
+ total: this.total,
394
+ byMethod: this.byMethod,
395
+ droppedByMethod: this.droppedByMethod,
396
+ reconnects: this.reconnects,
397
+ bodyCaptures: this.bodyCaptures
398
+ };
399
+ }
400
+ onEvent(method, rawParams, sessionId) {
401
+ if (!PERSIST_METHODS.has(method)) {
402
+ this.droppedByMethod[method] = (this.droppedByMethod[method] || 0) + 1;
403
+ return;
404
+ }
405
+ const params = asRec(rawParams);
406
+ this.trackRequest(method, params);
407
+ const shaped = this.shapePayloads(method, params);
408
+ const ev = { ts: Date.now(), kind: 'cdp', method, params: redact(shaped) };
409
+ if (sessionId)
410
+ ev.sessionId = sessionId;
411
+ this.writeLine(ev);
412
+ this.byMethod[method] = (this.byMethod[method] || 0) + 1;
413
+ if (method === 'Network.responseReceived')
414
+ this.maybeStreamContent(params);
415
+ if (method === 'Network.loadingFinished')
416
+ this.maybeFetchBody(params);
417
+ }
418
+ trackRequest(method, params) {
419
+ const requestId = typeof params.requestId === 'string' ? params.requestId : null;
420
+ if (!requestId)
421
+ return;
422
+ if (method === 'Network.requestWillBeSent') {
423
+ const req = asRec(params.request);
424
+ this.requests.set(requestId, {
425
+ url: String(req.url || ''),
426
+ resourceType: typeof params.type === 'string' ? params.type : null,
427
+ mimeType: null,
428
+ streamed: false,
429
+ bodyBytes: 0,
430
+ bodyFetched: false
431
+ });
432
+ }
433
+ else if (method === 'Network.responseReceived') {
434
+ const info = this.requests.get(requestId);
435
+ if (info) {
436
+ const resp = asRec(params.response);
437
+ info.mimeType = typeof resp.mimeType === 'string' ? resp.mimeType : null;
438
+ if (typeof params.type === 'string')
439
+ info.resourceType = params.type;
440
+ }
441
+ }
442
+ else if (method === 'Network.webSocketCreated') {
443
+ this.wsSocketUrls.set(requestId, String(params.url || ''));
444
+ }
445
+ }
446
+ /** Strip or size-cap payload-bearing fields before persistence. */
447
+ shapePayloads(method, params) {
448
+ if (method === 'Network.requestWillBeSent') {
449
+ const req = asRec(params.request);
450
+ if (typeof req.postData === 'string') {
451
+ // Off-origin: strip entirely. Kept (claude.ai) bodies are value-scrubbed
452
+ // so a credential in a sign-in/token POST body never lands verbatim.
453
+ if (!this.opts.captureBodiesFor.test(String(req.url || ''))) {
454
+ return { ...params, request: { ...req, postData: undefined, postDataBytes: req.postData.length } };
455
+ }
456
+ return { ...params, request: { ...req, postData: scrubSecrets(req.postData) } };
457
+ }
458
+ return params;
459
+ }
460
+ if (method === 'Network.webSocketFrameSent' || method === 'Network.webSocketFrameReceived') {
461
+ const requestId = String(params.requestId || '');
462
+ const socketUrl = this.wsSocketUrls.get(requestId) || '';
463
+ const resp = asRec(params.response);
464
+ if (typeof resp.payloadData === 'string') {
465
+ if (!this.opts.captureBodiesFor.test(socketUrl)) {
466
+ return { ...params, response: { ...resp, payloadData: undefined, payloadBytes: resp.payloadData.length } };
467
+ }
468
+ return { ...params, response: { ...resp, payloadData: scrubSecrets(resp.payloadData) } };
469
+ }
470
+ return params;
471
+ }
472
+ if (method === 'Network.dataReceived' && typeof params.data === 'string') {
473
+ const requestId = String(params.requestId || '');
474
+ const info = this.requests.get(requestId);
475
+ const bytes = Math.floor((params.data.length * 3) / 4);
476
+ if (info) {
477
+ if (info.bodyBytes + bytes > this.opts.maxBodyBytesPerRequest) {
478
+ return { ...params, data: undefined, dataDroppedBytes: bytes, truncated: true };
479
+ }
480
+ info.bodyBytes += bytes;
481
+ }
482
+ return params;
483
+ }
484
+ return params;
485
+ }
486
+ // Streaming responses (SSE / chunked fetch with no Content-Length) lose
487
+ // their bodies once the stream is consumed — getResponseBody after the
488
+ // fact usually fails. Network.streamResourceContent (experimental) asks
489
+ // Chrome to buffer + forward chunks as base64 on dataReceived. Best-effort:
490
+ // on older Chrome the command just rejects and chunk timing remains the
491
+ // primary record.
492
+ maybeStreamContent(params) {
493
+ const requestId = typeof params.requestId === 'string' ? params.requestId : null;
494
+ if (!requestId)
495
+ return;
496
+ const info = this.requests.get(requestId);
497
+ if (!info || info.streamed)
498
+ return;
499
+ if (!this.opts.captureBodiesFor.test(info.url))
500
+ return;
501
+ if (AUTH_URL_DENYLIST.test(info.url))
502
+ return;
503
+ if (!info.resourceType || !STREAMABLE_RESOURCE_TYPES.has(info.resourceType))
504
+ return;
505
+ const resp = asRec(params.response);
506
+ const headers = asRec(resp.headers);
507
+ const hasContentLength = Object.keys(headers).some((k) => k.toLowerCase() === 'content-length');
508
+ const isSse = info.mimeType === 'text/event-stream';
509
+ if (!isSse && hasContentLength)
510
+ return;
511
+ info.streamed = true;
512
+ const p = this.send('Network.streamResourceContent', { requestId })
513
+ .then((result) => {
514
+ const buffered = String(asRec(result).bufferedData || '');
515
+ const bytes = Math.floor((buffered.length * 3) / 4);
516
+ const truncated = bytes > this.opts.maxBodyBytesPerRequest;
517
+ info.bodyBytes += Math.min(bytes, this.opts.maxBodyBytesPerRequest);
518
+ this.bodyCaptures++;
519
+ this.writeLine({
520
+ ts: Date.now(),
521
+ kind: 'body',
522
+ requestId,
523
+ url: info.url,
524
+ source: 'streamBuffered',
525
+ base64: truncated ? buffered.slice(0, Math.ceil((this.opts.maxBodyBytesPerRequest * 4) / 3)) : buffered,
526
+ truncated,
527
+ bytes
528
+ });
529
+ })
530
+ .catch(() => {
531
+ info.streamed = false; // let loadingFinished try getResponseBody instead
532
+ })
533
+ .finally(() => this.pendingBodies.delete(p));
534
+ this.pendingBodies.add(p);
535
+ }
536
+ maybeFetchBody(params) {
537
+ const requestId = typeof params.requestId === 'string' ? params.requestId : null;
538
+ if (!requestId || this.stopped)
539
+ return;
540
+ const info = this.requests.get(requestId);
541
+ if (!info || info.streamed || info.bodyFetched)
542
+ return;
543
+ if (!this.opts.captureBodiesFor.test(info.url))
544
+ return;
545
+ if (AUTH_URL_DENYLIST.test(info.url))
546
+ return;
547
+ if (!info.resourceType || !STREAMABLE_RESOURCE_TYPES.has(info.resourceType))
548
+ return;
549
+ info.bodyFetched = true;
550
+ const p = this.send('Network.getResponseBody', { requestId })
551
+ .then((result) => {
552
+ const r = asRec(result);
553
+ const isB64 = r.base64Encoded === true;
554
+ // Text bodies are value-scrubbed before persistence; base64 (binary)
555
+ // bodies are opaque, so the auth-URL denylist above is their guard.
556
+ const body = isB64 ? String(r.body || '') : scrubSecrets(String(r.body || ''));
557
+ const bytes = isB64 ? Math.floor((body.length * 3) / 4) : body.length;
558
+ const truncated = bytes > this.opts.maxBodyBytesPerRequest;
559
+ const cap = isB64 ? Math.ceil((this.opts.maxBodyBytesPerRequest * 4) / 3) : this.opts.maxBodyBytesPerRequest;
560
+ this.bodyCaptures++;
561
+ this.writeLine({
562
+ ts: Date.now(),
563
+ kind: 'body',
564
+ requestId,
565
+ url: info.url,
566
+ source: 'getResponseBody',
567
+ base64: isB64 ? (truncated ? body.slice(0, cap) : body) : Buffer.from(truncated ? body.slice(0, cap) : body).toString('base64'),
568
+ truncated,
569
+ bytes
570
+ });
571
+ })
572
+ .catch((e) => {
573
+ this.writeLine({
574
+ ts: Date.now(),
575
+ kind: 'recorder',
576
+ event: 'error',
577
+ detail: { op: 'getResponseBody', requestId, url: info.url, message: e.message }
578
+ });
579
+ })
580
+ .finally(() => this.pendingBodies.delete(p));
581
+ this.pendingBodies.add(p);
582
+ }
583
+ onSocketGap() {
584
+ this.writeLine({ ts: Date.now(), kind: 'recorder', event: 'gap', detail: { reason: 'socket-closed' } });
585
+ }
586
+ onSocketReconnected(target) {
587
+ this.writeLine({ ts: Date.now(), kind: 'recorder', event: 'reconnect', detail: { targetUrl: target.url } });
588
+ }
589
+ onSocketReconnectFailed(detail) {
590
+ this.writeLine({ ts: Date.now(), kind: 'recorder', event: 'error', detail: { op: 'reconnect', ...detail } });
591
+ }
592
+ writeLine(ev) {
593
+ if (this.ended)
594
+ return; // a late body-fetch .catch can fire after stop() ended the stream
595
+ this.out.write(JSON.stringify(ev) + '\n');
596
+ this.total++;
597
+ }
598
+ }
599
+ exports.CdpTraceRecorder = CdpTraceRecorder;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.nodeSpawnSync = exports.nodeSpawn = exports.QUIT_CHROME_HINT = exports.WHICH = exports.xspawnSync = exports.xspawn = exports.IS_MAC = exports.IS_WIN = void 0;
7
+ exports.defaultChromeBin = defaultChromeBin;
8
+ exports.isChromeRunning = isChromeRunning;
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_child_process_1 = require("node:child_process");
12
+ Object.defineProperty(exports, "nodeSpawn", { enumerable: true, get: function () { return node_child_process_1.spawn; } });
13
+ Object.defineProperty(exports, "nodeSpawnSync", { enumerable: true, get: function () { return node_child_process_1.spawnSync; } });
14
+ const cross_spawn_1 = __importDefault(require("cross-spawn"));
15
+ exports.IS_WIN = process.platform === 'win32';
16
+ exports.IS_MAC = process.platform === 'darwin';
17
+ // Drop-in replacements for `child_process.spawn` / `spawnSync`.
18
+ //
19
+ // On Windows, npm-installed CLIs are `<name>.cmd` shims (sometimes `.ps1`)
20
+ // that Node ≥ 21 refuses to spawn directly (security policy: `EINVAL`), and
21
+ // that misbehave under `shell: true` when args contain shell metacharacters
22
+ // (parens, quotes, redirects — common in JS code passed to `agent-browser eval`).
23
+ //
24
+ // `cross-spawn` resolves shim paths and invokes them via `cmd /c` with proper
25
+ // argv quoting. Used by 100M+ npm packages; this is the standard fix.
26
+ //
27
+ // On macOS/Linux it's a passthrough to `child_process` — no behavior change.
28
+ exports.xspawn = cross_spawn_1.default;
29
+ exports.xspawnSync = cross_spawn_1.default.sync;
30
+ // Returns the `which` / `where` command name for the current OS.
31
+ exports.WHICH = exports.IS_WIN ? 'where' : 'which';
32
+ // Default Chrome binary path per OS. Override with the CHROME_BIN env var.
33
+ function defaultChromeBin() {
34
+ if (exports.IS_WIN) {
35
+ const candidates = [
36
+ node_path_1.default.join(process.env['ProgramFiles'] || 'C:\\Program Files', 'Google', 'Chrome', 'Application', 'chrome.exe'),
37
+ node_path_1.default.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'Google', 'Chrome', 'Application', 'chrome.exe'),
38
+ node_path_1.default.join(process.env['LOCALAPPDATA'] || '', 'Google', 'Chrome', 'Application', 'chrome.exe'),
39
+ ];
40
+ for (const c of candidates)
41
+ if (c && node_fs_1.default.existsSync(c))
42
+ return c;
43
+ return candidates[0] ?? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';
44
+ }
45
+ if (exports.IS_MAC)
46
+ return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
47
+ for (const c of ['/usr/bin/google-chrome', '/usr/bin/chromium', '/usr/bin/chromium-browser']) {
48
+ if (node_fs_1.default.existsSync(c))
49
+ return c;
50
+ }
51
+ return '/usr/bin/google-chrome';
52
+ }
53
+ // Cross-platform "is a non-debug Chrome currently running?" check.
54
+ function isChromeRunning() {
55
+ if (exports.IS_WIN) {
56
+ const r = (0, node_child_process_1.spawnSync)('tasklist', ['/FI', 'IMAGENAME eq chrome.exe', '/NH', '/FO', 'CSV'], { stdio: 'pipe' });
57
+ if (r.status !== 0)
58
+ return false;
59
+ const out = r.stdout?.toString() || '';
60
+ return out.toLowerCase().includes('chrome.exe');
61
+ }
62
+ if (exports.IS_MAC) {
63
+ const r = (0, node_child_process_1.spawnSync)('pgrep', ['-f', 'Google Chrome.app/Contents/MacOS/Google Chrome'], { stdio: 'pipe' });
64
+ return r.status === 0 && (r.stdout?.toString().trim().length ?? 0) > 0;
65
+ }
66
+ const r = (0, node_child_process_1.spawnSync)('pgrep', ['-f', 'chrome'], { stdio: 'pipe' });
67
+ return r.status === 0 && (r.stdout?.toString().trim().length ?? 0) > 0;
68
+ }
69
+ // User-friendly "press X to quit Chrome" hint per OS.
70
+ exports.QUIT_CHROME_HINT = exports.IS_WIN
71
+ ? 'Close all Chrome windows (or end chrome.exe in Task Manager).'
72
+ : exports.IS_MAC
73
+ ? 'Cmd+Q on the Chrome menu, then close Activity Monitor entries if any.'
74
+ : 'Close all Chrome windows or `pkill chrome`.';