xcoder-dna 0.0.0-stage → 1.3.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 (390) hide show
  1. package/LICENSE +66 -0
  2. package/README.md +87 -2
  3. package/dist/agents/ai-chat-debate.d.ts +36 -0
  4. package/dist/agents/ai-chat-debate.js +300 -0
  5. package/dist/agents/ai-chat-report-writer.d.ts +7 -0
  6. package/dist/agents/ai-chat-report-writer.js +100 -0
  7. package/dist/agents/duplicate-detector.d.ts +41 -0
  8. package/dist/agents/duplicate-detector.js +65 -0
  9. package/dist/agents/genesis-agent.d.ts +61 -0
  10. package/dist/agents/genesis-agent.js +340 -0
  11. package/dist/agents/samurai-agent.d.ts +53 -0
  12. package/dist/agents/samurai-agent.js +279 -0
  13. package/dist/agents/sub-agent.d.ts +56 -0
  14. package/dist/agents/sub-agent.js +353 -0
  15. package/dist/backlog/backlog-requirement-validator.d.ts +10 -0
  16. package/dist/backlog/backlog-requirement-validator.js +60 -0
  17. package/dist/backlog/backlog-store.d.ts +29 -0
  18. package/dist/backlog/backlog-store.js +148 -0
  19. package/dist/backlog/po-agent.d.ts +16 -0
  20. package/dist/backlog/po-agent.js +121 -0
  21. package/dist/backlog/types.d.ts +25 -0
  22. package/dist/backlog/types.js +4 -0
  23. package/dist/bench/run.d.ts +11 -0
  24. package/dist/bench/run.js +185 -0
  25. package/dist/bench/types.d.ts +50 -0
  26. package/dist/bench/types.js +1 -0
  27. package/dist/cli/swarm.d.ts +10 -0
  28. package/dist/cli/swarm.js +100 -0
  29. package/dist/cli/task.d.ts +14 -0
  30. package/dist/cli/task.js +121 -0
  31. package/dist/cli/wbc-arg.d.ts +6 -0
  32. package/dist/cli/wbc-arg.js +40 -0
  33. package/dist/cli/wbc.d.ts +45 -0
  34. package/dist/cli/wbc.js +98 -0
  35. package/dist/commands/license.d.ts +9 -0
  36. package/dist/commands/license.js +140 -0
  37. package/dist/commands/release.d.ts +44 -0
  38. package/dist/commands/release.js +180 -0
  39. package/dist/commands/test.d.ts +50 -0
  40. package/dist/commands/test.js +385 -0
  41. package/dist/config/loadConfig.d.ts +82 -0
  42. package/dist/config/loadConfig.js +240 -0
  43. package/dist/config/secure-mode.d.ts +29 -0
  44. package/dist/config/secure-mode.js +63 -0
  45. package/dist/config/user-config.d.ts +39 -0
  46. package/dist/config/user-config.js +202 -0
  47. package/dist/engine/reasoning-engine.d.ts +21 -0
  48. package/dist/engine/reasoning-engine.js +59 -0
  49. package/dist/events/bus.d.ts +22 -0
  50. package/dist/events/bus.js +18 -0
  51. package/dist/index.d.ts +79 -0
  52. package/dist/index.js +77 -0
  53. package/dist/indexing/ignoreRules.d.ts +1 -0
  54. package/dist/indexing/ignoreRules.js +53 -0
  55. package/dist/instance-swarm/instance-swarm-orchestrator.d.ts +57 -0
  56. package/dist/instance-swarm/instance-swarm-orchestrator.js +204 -0
  57. package/dist/instance-swarm/protocol-name-resolver.d.ts +23 -0
  58. package/dist/instance-swarm/protocol-name-resolver.js +64 -0
  59. package/dist/license/gate.d.ts +31 -0
  60. package/dist/license/gate.js +188 -0
  61. package/dist/license/http-client.d.ts +43 -0
  62. package/dist/license/http-client.js +195 -0
  63. package/dist/license/manager.d.ts +39 -0
  64. package/dist/license/manager.js +175 -0
  65. package/dist/license/receipt.d.ts +27 -0
  66. package/dist/license/receipt.js +108 -0
  67. package/dist/license/state-codec.d.ts +72 -0
  68. package/dist/license/state-codec.js +218 -0
  69. package/dist/license/state-paths.d.ts +17 -0
  70. package/dist/license/state-paths.js +64 -0
  71. package/dist/license/store.d.ts +44 -0
  72. package/dist/license/store.js +223 -0
  73. package/dist/license/trust-anchor.d.ts +24 -0
  74. package/dist/license/trust-anchor.js +74 -0
  75. package/dist/license/types.d.ts +34 -0
  76. package/dist/license/types.js +19 -0
  77. package/dist/llm/budget.d.ts +23 -0
  78. package/dist/llm/budget.js +58 -0
  79. package/dist/llm/client.d.ts +53 -0
  80. package/dist/llm/client.js +122 -0
  81. package/dist/llm/factory.d.ts +14 -0
  82. package/dist/llm/factory.js +32 -0
  83. package/dist/orchestrator/defect-logger.d.ts +31 -0
  84. package/dist/orchestrator/defect-logger.js +101 -0
  85. package/dist/orchestrator/defect-manager.d.ts +118 -0
  86. package/dist/orchestrator/defect-manager.js +338 -0
  87. package/dist/orchestrator/defect-migration.d.ts +14 -0
  88. package/dist/orchestrator/defect-migration.js +174 -0
  89. package/dist/orchestrator/defect-store.d.ts +48 -0
  90. package/dist/orchestrator/defect-store.js +76 -0
  91. package/dist/orchestrator/healing.d.ts +14 -0
  92. package/dist/orchestrator/healing.js +11 -0
  93. package/dist/orchestrator/interactive-steering.d.ts +64 -0
  94. package/dist/orchestrator/interactive-steering.js +107 -0
  95. package/dist/orchestrator/interrupt-handler.d.ts +30 -0
  96. package/dist/orchestrator/interrupt-handler.js +70 -0
  97. package/dist/orchestrator/lesson-manager.d.ts +25 -0
  98. package/dist/orchestrator/lesson-manager.js +122 -0
  99. package/dist/orchestrator/progress-summary.d.ts +15 -0
  100. package/dist/orchestrator/progress-summary.js +106 -0
  101. package/dist/orchestrator/reasoning-score.d.ts +49 -0
  102. package/dist/orchestrator/reasoning-score.js +117 -0
  103. package/dist/orchestrator/swarm.d.ts +36 -0
  104. package/dist/orchestrator/swarm.js +77 -0
  105. package/dist/orchestrator/task-factory.d.ts +15 -0
  106. package/dist/orchestrator/task-factory.js +176 -0
  107. package/dist/orchestrator/validation-gate.d.ts +23 -0
  108. package/dist/orchestrator/validation-gate.js +155 -0
  109. package/dist/protocol/react-contract.d.ts +136 -0
  110. package/dist/protocol/react-contract.js +698 -0
  111. package/dist/protocol/wks-protocol-manager.d.ts +22 -0
  112. package/dist/protocol/wks-protocol-manager.js +72 -0
  113. package/dist/sdlc-runtime/conversation-runner.d.ts +8 -0
  114. package/dist/sdlc-runtime/conversation-runner.js +64 -0
  115. package/dist/sdlc-runtime/dag-utils.d.ts +15 -0
  116. package/dist/sdlc-runtime/dag-utils.js +67 -0
  117. package/dist/sdlc-runtime/defect-integration.d.ts +7 -0
  118. package/dist/sdlc-runtime/defect-integration.js +99 -0
  119. package/dist/sdlc-runtime/execution-loop.d.ts +38 -0
  120. package/dist/sdlc-runtime/execution-loop.js +274 -0
  121. package/dist/sdlc-runtime/lesson-recorder.d.ts +9 -0
  122. package/dist/sdlc-runtime/lesson-recorder.js +27 -0
  123. package/dist/sdlc-runtime/plan-initializer.d.ts +47 -0
  124. package/dist/sdlc-runtime/plan-initializer.js +135 -0
  125. package/dist/sdlc-runtime/progress-persister.d.ts +10 -0
  126. package/dist/sdlc-runtime/progress-persister.js +34 -0
  127. package/dist/sdlc-runtime/protocol-loader.d.ts +10 -0
  128. package/dist/sdlc-runtime/protocol-loader.js +21 -0
  129. package/dist/sdlc-runtime/reporting.d.ts +24 -0
  130. package/dist/sdlc-runtime/reporting.js +68 -0
  131. package/dist/sdlc-runtime/sdlc-orchestrator.d.ts +59 -0
  132. package/dist/sdlc-runtime/sdlc-orchestrator.js +170 -0
  133. package/dist/sdlc-runtime/sdlc-skill.d.ts +44 -0
  134. package/dist/sdlc-runtime/sdlc-skill.js +148 -0
  135. package/dist/sdlc-runtime/steering-handler.d.ts +14 -0
  136. package/dist/sdlc-runtime/steering-handler.js +51 -0
  137. package/dist/sdlc-runtime/trace-recorder.d.ts +10 -0
  138. package/dist/sdlc-runtime/trace-recorder.js +7 -0
  139. package/dist/security/index.d.ts +16 -0
  140. package/dist/security/index.js +12 -0
  141. package/dist/security/input-screen.d.ts +30 -0
  142. package/dist/security/input-screen.js +75 -0
  143. package/dist/security/tool-call-guard.d.ts +16 -0
  144. package/dist/security/tool-call-guard.js +163 -0
  145. package/dist/security/untrusted-content.d.ts +34 -0
  146. package/dist/security/untrusted-content.js +63 -0
  147. package/dist/skills/advanced-dfir/SKILL.md +85 -0
  148. package/dist/skills/advanced-pentest-lab/SKILL.md +88 -0
  149. package/dist/skills/analyst/SKILL.md +55 -0
  150. package/dist/skills/architect/SKILL.md +54 -0
  151. package/dist/skills/aws/SKILL.md +92 -0
  152. package/dist/skills/azure/SKILL.md +90 -0
  153. package/dist/skills/bylaw-context.d.ts +45 -0
  154. package/dist/skills/bylaw-context.js +61 -0
  155. package/dist/skills/bylaw-review.d.ts +20 -0
  156. package/dist/skills/bylaw-review.js +101 -0
  157. package/dist/skills/conversation/SKILL.md +29 -0
  158. package/dist/skills/design-patterns/SKILL.md +190 -0
  159. package/dist/skills/devops/SKILL.md +55 -0
  160. package/dist/skills/directives.d.ts +20 -0
  161. package/dist/skills/directives.js +313 -0
  162. package/dist/skills/docker/SKILL.md +76 -0
  163. package/dist/skills/docker-expert/SKILL.md +56 -0
  164. package/dist/skills/enterprise-systems-analyst/SKILL.md +83 -0
  165. package/dist/skills/enterprise-systems-analyst/references/crm.md +41 -0
  166. package/dist/skills/enterprise-systems-analyst/references/erp.md +40 -0
  167. package/dist/skills/enterprise-systems-analyst/references/financial-systems.md +35 -0
  168. package/dist/skills/enterprise-systems-analyst/references/hcm.md +38 -0
  169. package/dist/skills/enterprise-systems-analyst/references/mrp.md +37 -0
  170. package/dist/skills/enterprise-systems-analyst/references/scm.md +32 -0
  171. package/dist/skills/ethical-hacking-methodology/SKILL.md +119 -0
  172. package/dist/skills/externalSkillLoader.d.ts +25 -0
  173. package/dist/skills/externalSkillLoader.js +65 -0
  174. package/dist/skills/externalSkillRegistry.d.ts +33 -0
  175. package/dist/skills/externalSkillRegistry.js +94 -0
  176. package/dist/skills/filesystem-management/SKILL.md +61 -0
  177. package/dist/skills/first-run-seed.d.ts +26 -0
  178. package/dist/skills/first-run-seed.js +75 -0
  179. package/dist/skills/git-vcs/SKILL.md +84 -0
  180. package/dist/skills/kafka/SKILL.md +89 -0
  181. package/dist/skills/kubernetes/SKILL.md +93 -0
  182. package/dist/skills/kubernetes-expert/SKILL.md +54 -0
  183. package/dist/skills/openshift/SKILL.md +93 -0
  184. package/dist/skills/pentester/SKILL.md +59 -0
  185. package/dist/skills/performance-tester/SKILL.md +57 -0
  186. package/dist/skills/playwright-ui-tester/SKILL.md +67 -0
  187. package/dist/skills/programmer/SKILL.md +58 -0
  188. package/dist/skills/project-scaffolding/SKILL.md +133 -0
  189. package/dist/skills/qa-engineer/SKILL.md +91 -0
  190. package/dist/skills/rca/SKILL.md +58 -0
  191. package/dist/skills/redhat/SKILL.md +92 -0
  192. package/dist/skills/rosa/SKILL.md +80 -0
  193. package/dist/skills/scrum-framework/SKILL.md +74 -0
  194. package/dist/skills/scrum-framework/references/artifacts_and_quality.md +79 -0
  195. package/dist/skills/scrum-framework/references/roles_and_events.md +105 -0
  196. package/dist/skills/scrum-master-agent/SKILL.md +74 -0
  197. package/dist/skills/scrum-master-agent/references/behaviors.md +56 -0
  198. package/dist/skills/sdlc-skill.d.ts +1 -0
  199. package/dist/skills/sdlc-skill.js +4 -0
  200. package/dist/skills/secops/SKILL.md +52 -0
  201. package/dist/skills/secure-architect.bylaws.d.ts +68 -0
  202. package/dist/skills/secure-architect.bylaws.js +525 -0
  203. package/dist/skills/seed-skills.d.ts +48 -0
  204. package/dist/skills/seed-skills.js +213 -0
  205. package/dist/skills/skill-authoring/SKILL.md +123 -0
  206. package/dist/skills/skill-header.d.ts +51 -0
  207. package/dist/skills/skill-header.js +163 -0
  208. package/dist/skills/skill-path-guard.d.ts +41 -0
  209. package/dist/skills/skill-path-guard.js +95 -0
  210. package/dist/skills/skillRouter.d.ts +51 -0
  211. package/dist/skills/skillRouter.js +90 -0
  212. package/dist/skills/skills-root.d.ts +64 -0
  213. package/dist/skills/skills-root.js +168 -0
  214. package/dist/skills/software-architect/SKILL.md +77 -0
  215. package/dist/skills/software-engineer/SKILL.md +74 -0
  216. package/dist/skills/solid-principles/SKILL.md +94 -0
  217. package/dist/skills/task-planning/SKILL.md +115 -0
  218. package/dist/skills/tester/SKILL.md +54 -0
  219. package/dist/skills/ubuntu/SKILL.md +87 -0
  220. package/dist/skills/ui-ux-design/SKILL.md +114 -0
  221. package/dist/skills/workspace-context/SKILL.md +103 -0
  222. package/dist/sprint/controller.d.ts +37 -0
  223. package/dist/sprint/controller.js +220 -0
  224. package/dist/sprint/dag-builder.d.ts +14 -0
  225. package/dist/sprint/dag-builder.js +105 -0
  226. package/dist/sprint/reporter.d.ts +11 -0
  227. package/dist/sprint/reporter.js +97 -0
  228. package/dist/sprint/state-store.d.ts +10 -0
  229. package/dist/sprint/state-store.js +71 -0
  230. package/dist/sprint/types.d.ts +24 -0
  231. package/dist/sprint/types.js +4 -0
  232. package/dist/store/file-version-store.d.ts +24 -0
  233. package/dist/store/file-version-store.js +73 -0
  234. package/dist/store/task-store.d.ts +90 -0
  235. package/dist/store/task-store.js +166 -0
  236. package/dist/task-ingest/architect-detailer.d.ts +43 -0
  237. package/dist/task-ingest/architect-detailer.js +141 -0
  238. package/dist/task-ingest/detail-schema.d.ts +9 -0
  239. package/dist/task-ingest/detail-schema.js +195 -0
  240. package/dist/task-ingest/detailed-run.d.ts +36 -0
  241. package/dist/task-ingest/detailed-run.js +108 -0
  242. package/dist/task-ingest/extract-id.d.ts +9 -0
  243. package/dist/task-ingest/extract-id.js +24 -0
  244. package/dist/task-ingest/index.d.ts +23 -0
  245. package/dist/task-ingest/index.js +14 -0
  246. package/dist/task-ingest/ingest.d.ts +45 -0
  247. package/dist/task-ingest/ingest.js +163 -0
  248. package/dist/task-ingest/list-ingested.d.ts +13 -0
  249. package/dist/task-ingest/list-ingested.js +30 -0
  250. package/dist/task-ingest/pending-filter.d.ts +30 -0
  251. package/dist/task-ingest/pending-filter.js +59 -0
  252. package/dist/task-ingest/scanner.d.ts +56 -0
  253. package/dist/task-ingest/scanner.js +216 -0
  254. package/dist/task-ingest/source-reader.d.ts +25 -0
  255. package/dist/task-ingest/source-reader.js +93 -0
  256. package/dist/task-ingest/spec-builder.d.ts +34 -0
  257. package/dist/task-ingest/spec-builder.js +89 -0
  258. package/dist/task-ingest/wbs-extract.d.ts +50 -0
  259. package/dist/task-ingest/wbs-extract.js +226 -0
  260. package/dist/task-ingest/wbs-parser.d.ts +36 -0
  261. package/dist/task-ingest/wbs-parser.js +170 -0
  262. package/dist/tools/apiTestTool.d.ts +37 -0
  263. package/dist/tools/apiTestTool.js +128 -0
  264. package/dist/tools/ast-tools.d.ts +183 -0
  265. package/dist/tools/ast-tools.js +853 -0
  266. package/dist/tools/browse-tool.d.ts +105 -0
  267. package/dist/tools/browse-tool.js +394 -0
  268. package/dist/tools/credential.d.ts +17 -0
  269. package/dist/tools/credential.js +32 -0
  270. package/dist/tools/dependency-graph.d.ts +23 -0
  271. package/dist/tools/dependency-graph.js +164 -0
  272. package/dist/tools/edit-tool.d.ts +34 -0
  273. package/dist/tools/edit-tool.js +95 -0
  274. package/dist/tools/file-header-manager.d.ts +27 -0
  275. package/dist/tools/file-header-manager.js +153 -0
  276. package/dist/tools/fs-tools.d.ts +154 -0
  277. package/dist/tools/fs-tools.js +337 -0
  278. package/dist/tools/git-tools.d.ts +79 -0
  279. package/dist/tools/git-tools.js +348 -0
  280. package/dist/tools/github-tool.d.ts +48 -0
  281. package/dist/tools/github-tool.js +147 -0
  282. package/dist/tools/globTool.d.ts +20 -0
  283. package/dist/tools/globTool.js +34 -0
  284. package/dist/tools/grepTool.d.ts +19 -0
  285. package/dist/tools/grepTool.js +44 -0
  286. package/dist/tools/index-freshness.d.ts +58 -0
  287. package/dist/tools/index-freshness.js +190 -0
  288. package/dist/tools/index-glob.d.ts +48 -0
  289. package/dist/tools/index-glob.js +175 -0
  290. package/dist/tools/load-skill-tool.d.ts +15 -0
  291. package/dist/tools/load-skill-tool.js +114 -0
  292. package/dist/tools/patch-tools.d.ts +58 -0
  293. package/dist/tools/patch-tools.js +153 -0
  294. package/dist/tools/playwright-tool.d.ts +66 -0
  295. package/dist/tools/playwright-tool.js +121 -0
  296. package/dist/tools/project-detect.d.ts +20 -0
  297. package/dist/tools/project-detect.js +87 -0
  298. package/dist/tools/prompt-guidance.d.ts +22 -0
  299. package/dist/tools/prompt-guidance.js +23 -0
  300. package/dist/tools/scheduleTool.d.ts +19 -0
  301. package/dist/tools/scheduleTool.js +181 -0
  302. package/dist/tools/search-tools.d.ts +27 -0
  303. package/dist/tools/search-tools.js +78 -0
  304. package/dist/tools/sed-tool.d.ts +66 -0
  305. package/dist/tools/sed-tool.js +402 -0
  306. package/dist/tools/shell-result.d.ts +11 -0
  307. package/dist/tools/shell-result.js +1 -0
  308. package/dist/tools/shell-tool.d.ts +45 -0
  309. package/dist/tools/shell-tool.js +141 -0
  310. package/dist/tools/siteCrawlerTool.d.ts +32 -0
  311. package/dist/tools/siteCrawlerTool.js +205 -0
  312. package/dist/tools/tool-registry.d.ts +67 -0
  313. package/dist/tools/tool-registry.js +596 -0
  314. package/dist/tools/validate-tool.d.ts +23 -0
  315. package/dist/tools/validate-tool.js +201 -0
  316. package/dist/tools/workspace-index.d.ts +46 -0
  317. package/dist/tools/workspace-index.js +173 -0
  318. package/dist/types.d.ts +222 -0
  319. package/dist/types.js +7 -0
  320. package/dist/updater/index.d.ts +14 -0
  321. package/dist/updater/index.js +120 -0
  322. package/dist/util/banner.d.ts +25 -0
  323. package/dist/util/banner.js +140 -0
  324. package/dist/util/command-suggester.d.ts +6 -0
  325. package/dist/util/command-suggester.js +25 -0
  326. package/dist/util/confirm-interrupt.d.ts +10 -0
  327. package/dist/util/confirm-interrupt.js +31 -0
  328. package/dist/util/continue-trigger.d.ts +11 -0
  329. package/dist/util/continue-trigger.js +20 -0
  330. package/dist/util/env-info.d.ts +18 -0
  331. package/dist/util/env-info.js +37 -0
  332. package/dist/util/file-access-log.d.ts +35 -0
  333. package/dist/util/file-access-log.js +140 -0
  334. package/dist/util/footer-manager.d.ts +124 -0
  335. package/dist/util/footer-manager.js +195 -0
  336. package/dist/util/footer-renderer.d.ts +67 -0
  337. package/dist/util/footer-renderer.js +319 -0
  338. package/dist/util/footer-state.d.ts +34 -0
  339. package/dist/util/footer-state.js +18 -0
  340. package/dist/util/footer-text.d.ts +51 -0
  341. package/dist/util/footer-text.js +74 -0
  342. package/dist/util/ids.d.ts +1 -0
  343. package/dist/util/ids.js +4 -0
  344. package/dist/util/levenshtein.d.ts +6 -0
  345. package/dist/util/levenshtein.js +34 -0
  346. package/dist/util/logger.d.ts +10 -0
  347. package/dist/util/logger.js +41 -0
  348. package/dist/util/logs.d.ts +26 -0
  349. package/dist/util/logs.js +88 -0
  350. package/dist/util/output-handler.d.ts +89 -0
  351. package/dist/util/output-handler.js +193 -0
  352. package/dist/util/output-interceptor.d.ts +18 -0
  353. package/dist/util/output-interceptor.js +49 -0
  354. package/dist/util/output-paths.d.ts +43 -0
  355. package/dist/util/output-paths.js +121 -0
  356. package/dist/util/package-json.d.ts +6 -0
  357. package/dist/util/package-json.js +36 -0
  358. package/dist/util/process-kill.d.ts +27 -0
  359. package/dist/util/process-kill.js +148 -0
  360. package/dist/util/protocol-error-logger.d.ts +33 -0
  361. package/dist/util/protocol-error-logger.js +73 -0
  362. package/dist/util/redact.d.ts +25 -0
  363. package/dist/util/redact.js +103 -0
  364. package/dist/util/scroll-region-guard.d.ts +33 -0
  365. package/dist/util/scroll-region-guard.js +63 -0
  366. package/dist/util/spinner.d.ts +15 -0
  367. package/dist/util/spinner.js +49 -0
  368. package/dist/util/terminal-output.d.ts +34 -0
  369. package/dist/util/terminal-output.js +1 -0
  370. package/dist/util/terminal-silent.d.ts +6 -0
  371. package/dist/util/terminal-silent.js +20 -0
  372. package/dist/util/terminal.d.ts +56 -0
  373. package/dist/util/terminal.js +124 -0
  374. package/dist/util/text-sanitize.d.ts +8 -0
  375. package/dist/util/text-sanitize.js +45 -0
  376. package/dist/util/thinking-spinner.d.ts +27 -0
  377. package/dist/util/thinking-spinner.js +189 -0
  378. package/dist/util/tool-error-logger.d.ts +33 -0
  379. package/dist/util/tool-error-logger.js +77 -0
  380. package/dist/util/tty.d.ts +13 -0
  381. package/dist/util/tty.js +16 -0
  382. package/dist/util/xcoder-paths.d.ts +56 -0
  383. package/dist/util/xcoder-paths.js +63 -0
  384. package/dist/version.d.ts +2 -0
  385. package/dist/version.js +4 -0
  386. package/dist/worker-agent/to-subtask-node.d.ts +35 -0
  387. package/dist/worker-agent/to-subtask-node.js +41 -0
  388. package/dist/worker-agent/worker-orchestrator.d.ts +104 -0
  389. package/dist/worker-agent/worker-orchestrator.js +201 -0
  390. package/package.json +39 -4
@@ -0,0 +1,402 @@
1
+ // xcoder:version 2 | xcoder:task task-456d3f | xcoder:updated 2026-08-03T15:41:37.782Z | xcoder:subtask code-st-97a4d4
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+ import { getOrBuildIndex, upsertEntry, toPosixPath } from "./workspace-index.js";
5
+ import { indexGlobTool } from "./search-tools.js";
6
+ import { getCommentSyntax, injectVersionHeader, } from "./file-header-manager.js";
7
+ import { incrementFileVersion } from "../store/file-version-store.js";
8
+ // ── Constants ────────────────────────────────────────────────────────────
9
+ const ALLOWED_FLAGS = new Set(["g", "i", "m", "s"]);
10
+ // ── Helpers ──────────────────────────────────────────────────────────────
11
+ class WorkspaceEscapeError extends Error {
12
+ }
13
+ function resolveInWorkspace(root, relPath) {
14
+ const full = path.resolve(root, relPath);
15
+ const normalizedRoot = path.resolve(root) + path.sep;
16
+ if (full + path.sep !== normalizedRoot && !full.startsWith(normalizedRoot)) {
17
+ throw new WorkspaceEscapeError(`path "${relPath}" resolves outside the workspace root — refusing.`);
18
+ }
19
+ return full;
20
+ }
21
+ /**
22
+ * Validate the SedToolInput before processing.
23
+ * Returns an error string if invalid, null if valid.
24
+ */
25
+ function validateInput(input) {
26
+ // Operation must be valid
27
+ const validOps = ["substitute", "delete", "deleteRange", "insert", "appendAfter"];
28
+ if (!validOps.includes(input.operation)) {
29
+ return `invalid_operation: "${input.operation}" is not a valid operation. Must be one of: ${validOps.join(", ")}`;
30
+ }
31
+ // Target: glob takes precedence, then path, then neither → no_target
32
+ const hasPath = input.path !== undefined && input.path !== "";
33
+ const hasGlob = input.glob !== undefined && input.glob !== "";
34
+ if (!hasPath && !hasGlob) {
35
+ return "no_target: neither 'path' nor 'glob' was provided. Provide at least one target.";
36
+ }
37
+ // Operation-specific validation
38
+ switch (input.operation) {
39
+ case "substitute":
40
+ if (input.pattern === undefined || input.pattern === "") {
41
+ return "invalid_operation: 'substitute' requires a 'pattern' field.";
42
+ }
43
+ if (input.replacement === undefined) {
44
+ return "invalid_operation: 'substitute' requires a 'replacement' field.";
45
+ }
46
+ break;
47
+ case "delete":
48
+ if (input.pattern === undefined || input.pattern === "") {
49
+ return "invalid_operation: 'delete' requires a 'pattern' field.";
50
+ }
51
+ break;
52
+ case "deleteRange":
53
+ if (input.startLine === undefined || input.endLine === undefined) {
54
+ return "invalid_operation: 'deleteRange' requires both 'startLine' and 'endLine'.";
55
+ }
56
+ if (!Number.isInteger(input.startLine) || input.startLine < 1) {
57
+ return "invalid_operation: 'startLine' must be an integer >= 1.";
58
+ }
59
+ if (!Number.isInteger(input.endLine) || input.endLine < 1) {
60
+ return "invalid_operation: 'endLine' must be an integer >= 1.";
61
+ }
62
+ if (input.endLine < input.startLine) {
63
+ return "invalid_operation: 'endLine' must be >= 'startLine'.";
64
+ }
65
+ break;
66
+ case "insert":
67
+ if (input.text === undefined) {
68
+ return "invalid_operation: 'insert' requires a 'text' field.";
69
+ }
70
+ if (input.afterLine !== undefined && (!Number.isInteger(input.afterLine) || input.afterLine < 0)) {
71
+ return "invalid_operation: 'afterLine' must be an integer >= 0.";
72
+ }
73
+ break;
74
+ case "appendAfter":
75
+ if (input.pattern === undefined || input.pattern === "") {
76
+ return "invalid_operation: 'appendAfter' requires a 'pattern' field.";
77
+ }
78
+ if (input.text === undefined) {
79
+ return "invalid_operation: 'appendAfter' requires a 'text' field.";
80
+ }
81
+ break;
82
+ }
83
+ // Flags validation (if provided)
84
+ if (input.flags !== undefined) {
85
+ for (const ch of input.flags) {
86
+ if (!ALLOWED_FLAGS.has(ch)) {
87
+ return `invalid_regex: flag "${ch}" is not allowed. Allowed flags: ${[...ALLOWED_FLAGS].join("")}`;
88
+ }
89
+ }
90
+ }
91
+ // Regex validation (if pattern provided)
92
+ if (input.pattern) {
93
+ try {
94
+ new RegExp(input.pattern, input.flags ?? "");
95
+ }
96
+ catch (e) {
97
+ return `invalid_regex: ${e.message}`;
98
+ }
99
+ }
100
+ return null; // valid
101
+ }
102
+ // ── Target Resolution ────────────────────────────────────────────────────
103
+ /**
104
+ * Resolve target files: glob takes precedence over path.
105
+ */
106
+ async function resolveTargetFiles(root, input) {
107
+ if (input.glob !== undefined && input.glob !== "") {
108
+ const index = await getOrBuildIndex(root);
109
+ const result = indexGlobTool(index, input.glob);
110
+ return result.matches;
111
+ }
112
+ if (input.path !== undefined && input.path !== "") {
113
+ return [input.path];
114
+ }
115
+ return [];
116
+ }
117
+ // ── Line Ending Detection & Normalization ────────────────────────────────
118
+ function detectLineEndings(content) {
119
+ const crlfCount = (content.match(/\r\n/g) || []).length;
120
+ // Match LF not preceded by CR (pure LF lines)
121
+ const lfOnlyCount = (content.match(/(?<!\r)\n/g) || []).length;
122
+ if (crlfCount > 0 && lfOnlyCount === 0)
123
+ return "CRLF";
124
+ if (lfOnlyCount > 0 && crlfCount === 0)
125
+ return "LF";
126
+ if (crlfCount === 0 && lfOnlyCount === 0)
127
+ return "LF"; // empty or single line without newline
128
+ return "mixed";
129
+ }
130
+ function normalizeToLF(content, _style) {
131
+ return content.replace(/\r\n/g, "\n");
132
+ }
133
+ function restoreLineEndings(normalized, style) {
134
+ if (style === "CRLF") {
135
+ return normalized.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n");
136
+ }
137
+ return normalized;
138
+ }
139
+ // ── Operations ───────────────────────────────────────────────────────────
140
+ function buildRegex(pattern, flags) {
141
+ return new RegExp(pattern, flags);
142
+ }
143
+ /**
144
+ * Replace back-reference placeholders in the replacement string.
145
+ * Supports $& (full match), $1-$9 (capture groups), and $$ (literal $).
146
+ */
147
+ function expandReplacement(replacement, match, ...groups) {
148
+ return replacement.replace(/\$([&1-9]|\$)/g, (_, ref) => {
149
+ if (ref === "&")
150
+ return match;
151
+ if (ref === "$")
152
+ return "$";
153
+ const idx = parseInt(ref, 10);
154
+ return groups[idx - 1] ?? "$" + ref;
155
+ });
156
+ }
157
+ function applySubstitute(lines, pattern, replacement, flags) {
158
+ const re = buildRegex(pattern, flags);
159
+ let changes = 0;
160
+ const result = lines.map((line) => {
161
+ let changed = false;
162
+ const newLine = line.replace(re, (...args) => {
163
+ changed = true;
164
+ const match = args[0];
165
+ const groups = args.slice(1, -2);
166
+ return expandReplacement(replacement, match, ...groups);
167
+ });
168
+ if (changed)
169
+ changes++;
170
+ return newLine;
171
+ });
172
+ return { lines: result, changes };
173
+ }
174
+ function applyDelete(lines, pattern, flags) {
175
+ const re = buildRegex(pattern, flags);
176
+ let changes = 0;
177
+ const result = lines.filter((line) => {
178
+ const match = re.test(line);
179
+ if (match)
180
+ changes++;
181
+ return !match;
182
+ });
183
+ return { lines: result, changes };
184
+ }
185
+ function applyDeleteRange(lines, startLine, endLine) {
186
+ const max = lines.length;
187
+ const start = Math.max(1, startLine);
188
+ const end = Math.min(max, endLine);
189
+ if (start > max || end < start) {
190
+ return { lines, changes: 0 };
191
+ }
192
+ const count = end - start + 1;
193
+ const result = [...lines.slice(0, start - 1), ...lines.slice(end)];
194
+ return { lines: result, changes: count };
195
+ }
196
+ function applyInsert(lines, afterLine, text) {
197
+ // afterLine 0 = before first line
198
+ // Clamp: if afterLine > lines.length, append at end
199
+ const pos = Math.min(afterLine, lines.length);
200
+ const result = [...lines.slice(0, pos), text, ...lines.slice(pos)];
201
+ return { lines: result, changes: 1 };
202
+ }
203
+ function applyAppendAfter(lines, pattern, text, flags) {
204
+ const re = buildRegex(pattern, flags);
205
+ let changes = 0;
206
+ const result = [];
207
+ for (const line of lines) {
208
+ result.push(line);
209
+ if (re.test(line)) {
210
+ result.push(text);
211
+ changes++;
212
+ }
213
+ }
214
+ return { lines: result, changes };
215
+ }
216
+ // ── Per-File Processing ──────────────────────────────────────────────────
217
+ async function processFile(root, relPath, input, ctx) {
218
+ let full;
219
+ try {
220
+ full = resolveInWorkspace(root, relPath);
221
+ }
222
+ catch {
223
+ return {
224
+ relPath,
225
+ matched: false,
226
+ changes: 0,
227
+ output: undefined,
228
+ };
229
+ }
230
+ // Read file
231
+ let content;
232
+ try {
233
+ content = await fs.readFile(full, "utf8");
234
+ }
235
+ catch {
236
+ return {
237
+ relPath,
238
+ matched: false,
239
+ changes: 0,
240
+ output: undefined,
241
+ };
242
+ }
243
+ // Detect and normalize line endings
244
+ const lineEndingStyle = detectLineEndings(content);
245
+ const normalized = normalizeToLF(content, lineEndingStyle);
246
+ // Split into lines. A trailing empty string from split("\n") represents
247
+ // a trailing newline in the file — we strip it before operating on
248
+ // "real" lines (so line counts match user expectations), then re-add it
249
+ // after the join so the file's trailing-newline convention is preserved.
250
+ const rawLines = normalized.split("\n");
251
+ const hasTrailingNewline = rawLines.length > 0 && rawLines[rawLines.length - 1] === "";
252
+ const lines = hasTrailingNewline ? rawLines.slice(0, -1) : rawLines;
253
+ // Apply operation
254
+ let resultLines;
255
+ let changes;
256
+ switch (input.operation) {
257
+ case "substitute": {
258
+ const r = applySubstitute(lines, input.pattern, input.replacement, input.flags ?? "g");
259
+ resultLines = r.lines;
260
+ changes = r.changes;
261
+ break;
262
+ }
263
+ case "delete": {
264
+ const r = applyDelete(lines, input.pattern, input.flags ?? "");
265
+ resultLines = r.lines;
266
+ changes = r.changes;
267
+ break;
268
+ }
269
+ case "deleteRange": {
270
+ const r = applyDeleteRange(lines, input.startLine, input.endLine);
271
+ resultLines = r.lines;
272
+ changes = r.changes;
273
+ break;
274
+ }
275
+ case "insert": {
276
+ const r = applyInsert(lines, input.afterLine ?? lines.length, input.text);
277
+ resultLines = r.lines;
278
+ changes = r.changes;
279
+ break;
280
+ }
281
+ case "appendAfter": {
282
+ const r = applyAppendAfter(lines, input.pattern, input.text, input.flags ?? "");
283
+ resultLines = r.lines;
284
+ changes = r.changes;
285
+ break;
286
+ }
287
+ default:
288
+ return { relPath, matched: false, changes: 0 };
289
+ }
290
+ // Rejoin and restore line endings. Preserve trailing newline convention.
291
+ const joined = resultLines.join("\n") + (hasTrailingNewline ? "\n" : "");
292
+ const outputContent = restoreLineEndings(joined, lineEndingStyle);
293
+ const matched = changes > 0;
294
+ // Dry run: return output but don't write
295
+ if (input.dryRun) {
296
+ return { relPath, matched, changes, output: outputContent };
297
+ }
298
+ // Write back (with optional header injection)
299
+ try {
300
+ let finalContent = outputContent;
301
+ if (matched && ctx) {
302
+ const syntax = getCommentSyntax(relPath);
303
+ if (syntax) {
304
+ const meta = await incrementFileVersion(root, relPath, ctx.taskId, ctx.subtaskId);
305
+ const injected = injectVersionHeader(finalContent, syntax, meta);
306
+ finalContent = injected.content;
307
+ }
308
+ }
309
+ await fs.writeFile(full, finalContent, "utf8");
310
+ await upsertEntry(root, path.relative(root, full));
311
+ return { relPath, matched, changes };
312
+ }
313
+ catch {
314
+ return { relPath, matched: false, changes: 0 };
315
+ }
316
+ }
317
+ // ── Main Export ──────────────────────────────────────────────────────────
318
+ /**
319
+ * Perform stream-editing operations on workspace files.
320
+ * Supports substitute, delete, deleteRange, insert, and appendAfter operations.
321
+ */
322
+ export async function sedTool(root, input, ctx) {
323
+ // Validate input
324
+ const validationError = validateInput(input);
325
+ if (validationError) {
326
+ const code = validationError.startsWith("no_target")
327
+ ? "no_target"
328
+ : validationError.startsWith("invalid_regex")
329
+ ? "invalid_regex"
330
+ : "invalid_operation";
331
+ return { ok: false, code, error: validationError };
332
+ }
333
+ // Resolve target files
334
+ let targetFiles;
335
+ try {
336
+ targetFiles = await resolveTargetFiles(root, input);
337
+ }
338
+ catch (e) {
339
+ return { ok: false, code: "io_error", error: `Failed to resolve target files: ${e.message}` };
340
+ }
341
+ if (targetFiles.length === 0) {
342
+ const target = input.glob ? `glob "${input.glob}"` : `path "${input.path}"`;
343
+ return {
344
+ ok: false,
345
+ code: "file_not_found",
346
+ error: `No files matched ${target}. Check the pattern or run reindex_workspace to refresh the index.`,
347
+ };
348
+ }
349
+ // When using a single path (not glob), verify the file actually exists
350
+ // on disk before proceeding.
351
+ if (!input.glob && input.path) {
352
+ try {
353
+ const full = resolveInWorkspace(root, input.path);
354
+ try {
355
+ await fs.access(full);
356
+ }
357
+ catch {
358
+ return {
359
+ ok: false,
360
+ code: "file_not_found",
361
+ error: `File "${input.path}" does not exist in the workspace.`,
362
+ };
363
+ }
364
+ }
365
+ catch {
366
+ return {
367
+ ok: false,
368
+ code: "workspace_escape",
369
+ error: `Path "${input.path}" resolves outside the workspace root.`,
370
+ };
371
+ }
372
+ }
373
+ // Process each file
374
+ const results = [];
375
+ let workspaceEscape = false;
376
+ for (const relPath of targetFiles) {
377
+ // Check for workspace escape
378
+ try {
379
+ resolveInWorkspace(root, relPath);
380
+ }
381
+ catch {
382
+ workspaceEscape = true;
383
+ continue;
384
+ }
385
+ const posixPath = toPosixPath(relPath).replace(/^\.\//, "");
386
+ try {
387
+ const result = await processFile(root, posixPath, input, ctx);
388
+ results.push(result);
389
+ }
390
+ catch {
391
+ results.push({ relPath: posixPath, matched: false, changes: 0 });
392
+ }
393
+ }
394
+ if (workspaceEscape && results.length === 0) {
395
+ return {
396
+ ok: false,
397
+ code: "workspace_escape",
398
+ error: `One or more target paths resolve outside the workspace root.`,
399
+ };
400
+ }
401
+ return { ok: true, results };
402
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared result interface for shell command execution.
3
+ * Used by both shell-tool.ts (exec-based) and runCommandTool.ts (spawn-based).
4
+ */
5
+ export interface ShellResult {
6
+ ok: boolean;
7
+ exitCode: number | null;
8
+ stdout: string;
9
+ stderr: string;
10
+ timedOut: boolean;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import type { ShellResult } from "./shell-result.js";
2
+ export type { ShellResult } from "./shell-result.js";
3
+ /**
4
+ * Minimal shell-quote-aware split: respects single-quoted and double-quoted
5
+ * strings. Does NOT handle escaped quotes, nested quoting, or advanced
6
+ * features — it just needs to be good enough to split "npm run build" into
7
+ * ["npm", "run", "build"] and preserve "echo 'hello world'" as
8
+ * ["echo", "hello world"].
9
+ *
10
+ * Migrated from runCommandTool.ts. Exported for testing but intended as
11
+ * an internal utility of shell-tool.ts.
12
+ */
13
+ export declare function splitCommand(command: string): string[];
14
+ /**
15
+ * Windows-specific PATHEXT resolution: wraps .cmd/.bat/.ps1 commands
16
+ * with the appropriate interpreter so they work on Windows even when
17
+ * passed to exec(). This is a transparent safety net — exec() already
18
+ * handles .cmd/.bat natively in many shells, but wrapping ensures
19
+ * consistent behavior across all Windows configurations.
20
+ *
21
+ * On non-Windows platforms this is a no-op.
22
+ *
23
+ * Migrated from runCommandTool.ts. Exported for testing but intended as
24
+ * an internal utility of shell-tool.ts.
25
+ */
26
+ export declare function resolveWindowsExecutable(command: string, args: string[]): {
27
+ command: string;
28
+ args: string[];
29
+ };
30
+ export declare function isDenied(command: string): string | null;
31
+ /**
32
+ * The single entry point for executing shell commands via the run_command
33
+ * tool. Internally:
34
+ * 1. Checks the denylist — denied commands return immediately.
35
+ * 2. Splits the command to identify the executable.
36
+ * 3. On Windows, wraps .cmd/.bat/.ps1 executables with the appropriate
37
+ * interpreter via resolveWindowsExecutable().
38
+ * 4. Executes via child_process.exec().
39
+ *
40
+ * @param command - The full command string, e.g. "npm run build".
41
+ * @param cwd - Working directory (the workspace root).
42
+ * @param timeoutMs - Optional timeout in milliseconds (default 120_000).
43
+ * @returns A ShellResult promise.
44
+ */
45
+ export declare function runCommandTool(command: string, cwd: string, timeoutMs?: number): Promise<ShellResult>;
@@ -0,0 +1,141 @@
1
+ // xcoder:version 2 | xcoder:task task-a73fdc | xcoder:updated 2026-08-03T20:52:06.503Z | xcoder:subtask code-st-dd8b38
2
+ import { exec } from "node:child_process";
3
+ /**
4
+ * A denylist, not a sandbox. This catches the obviously destructive
5
+ * one-liners a model might produce while "cleaning up" or "starting
6
+ * fresh" — it is NOT a security boundary against an adversarial actor.
7
+ * Xcoder SDLC is designed to run each task inside its own disposable container
8
+ * or VM (the same isolation principle Agent Factory's Tool Execution
9
+ * Sandbox uses) — this denylist is a courtesy guardrail on top of that,
10
+ * not a substitute for it.
11
+ */
12
+ const DENYLIST_PATTERNS = [
13
+ /\brm\s+-rf\s+\/(?:\s|$)/, // rm -rf /
14
+ /\brm\s+-rf\s+~(?:\s|$)/, // rm -rf ~
15
+ /\bmkfs\b/,
16
+ /:\(\)\{.*:\|:.*\};:/, // fork bomb
17
+ /\bdd\s+if=.*of=\/dev\/(sd|nvme|hd)/,
18
+ /\bchmod\s+-R\s+777\s+\//,
19
+ /\bcurl\b.*\|\s*sh\b/, // pipe-to-shell from a URL — force an explicit review step instead
20
+ />\s*\/dev\/sd/,
21
+ ];
22
+ /**
23
+ * Minimal shell-quote-aware split: respects single-quoted and double-quoted
24
+ * strings. Does NOT handle escaped quotes, nested quoting, or advanced
25
+ * features — it just needs to be good enough to split "npm run build" into
26
+ * ["npm", "run", "build"] and preserve "echo 'hello world'" as
27
+ * ["echo", "hello world"].
28
+ *
29
+ * Migrated from runCommandTool.ts. Exported for testing but intended as
30
+ * an internal utility of shell-tool.ts.
31
+ */
32
+ export function splitCommand(command) {
33
+ const parts = [];
34
+ let current = "";
35
+ let quote = null;
36
+ for (let i = 0; i < command.length; i++) {
37
+ const ch = command[i];
38
+ if (quote) {
39
+ if (ch === quote) {
40
+ quote = null;
41
+ }
42
+ else {
43
+ current += ch;
44
+ }
45
+ }
46
+ else if (ch === "'" || ch === '"') {
47
+ quote = ch;
48
+ }
49
+ else if (ch === " " || ch === "\t") {
50
+ if (current.length > 0) {
51
+ parts.push(current);
52
+ current = "";
53
+ }
54
+ }
55
+ else {
56
+ current += ch;
57
+ }
58
+ }
59
+ if (current.length > 0) {
60
+ parts.push(current);
61
+ }
62
+ return parts;
63
+ }
64
+ /**
65
+ * Windows-specific PATHEXT resolution: wraps .cmd/.bat/.ps1 commands
66
+ * with the appropriate interpreter so they work on Windows even when
67
+ * passed to exec(). This is a transparent safety net — exec() already
68
+ * handles .cmd/.bat natively in many shells, but wrapping ensures
69
+ * consistent behavior across all Windows configurations.
70
+ *
71
+ * On non-Windows platforms this is a no-op.
72
+ *
73
+ * Migrated from runCommandTool.ts. Exported for testing but intended as
74
+ * an internal utility of shell-tool.ts.
75
+ */
76
+ export function resolveWindowsExecutable(command, args) {
77
+ if (process.platform !== "win32")
78
+ return { command, args };
79
+ const lower = command.toLowerCase();
80
+ if (lower.endsWith(".cmd") || lower.endsWith(".bat")) {
81
+ return { command: "cmd.exe", args: ["/c", command, ...args] };
82
+ }
83
+ if (lower.endsWith(".ps1")) {
84
+ return { command: "powershell.exe", args: ["-File", command, ...args] };
85
+ }
86
+ return { command, args };
87
+ }
88
+ export function isDenied(command) {
89
+ for (const pattern of DENYLIST_PATTERNS) {
90
+ if (pattern.test(command)) {
91
+ return `command matches a denylisted destructive pattern (${pattern}) and was not run.`;
92
+ }
93
+ }
94
+ return null;
95
+ }
96
+ /**
97
+ * The single entry point for executing shell commands via the run_command
98
+ * tool. Internally:
99
+ * 1. Checks the denylist — denied commands return immediately.
100
+ * 2. Splits the command to identify the executable.
101
+ * 3. On Windows, wraps .cmd/.bat/.ps1 executables with the appropriate
102
+ * interpreter via resolveWindowsExecutable().
103
+ * 4. Executes via child_process.exec().
104
+ *
105
+ * @param command - The full command string, e.g. "npm run build".
106
+ * @param cwd - Working directory (the workspace root).
107
+ * @param timeoutMs - Optional timeout in milliseconds (default 120_000).
108
+ * @returns A ShellResult promise.
109
+ */
110
+ export function runCommandTool(command, cwd, timeoutMs = 120_000) {
111
+ const denyReason = isDenied(command);
112
+ if (denyReason) {
113
+ return Promise.resolve({ ok: false, exitCode: null, stdout: "", stderr: denyReason, timedOut: false });
114
+ }
115
+ // Apply OS-aware executable wrapping for Windows .cmd/.bat/.ps1 commands
116
+ const trimmed = command.trim();
117
+ let finalCommand = trimmed;
118
+ if (trimmed.length > 0 && process.platform === "win32") {
119
+ const parts = splitCommand(trimmed);
120
+ const executable = parts[0];
121
+ const rawArgs = parts.slice(1);
122
+ const { command: resolvedCmd, args } = resolveWindowsExecutable(executable, rawArgs);
123
+ if (resolvedCmd !== executable) {
124
+ // The executable was wrapped — reconstruct the command string
125
+ finalCommand = [resolvedCmd, ...args].map((a) => a.includes(" ") ? `"${a}"` : a).join(" ");
126
+ }
127
+ }
128
+ return new Promise((resolve) => {
129
+ const child = exec(finalCommand, { cwd, timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
130
+ const timedOut = !!error && error.killed === true && error.signal === "SIGTERM";
131
+ resolve({
132
+ ok: !error,
133
+ exitCode: error ? (typeof error.code === "number" ? error.code : 1) : 0,
134
+ stdout,
135
+ stderr,
136
+ timedOut,
137
+ });
138
+ });
139
+ void child;
140
+ });
141
+ }
@@ -0,0 +1,32 @@
1
+ export interface SitePage {
2
+ url: string;
3
+ title: string;
4
+ depth: number;
5
+ links: string[];
6
+ status: number;
7
+ }
8
+ export interface SiteMap {
9
+ rootUrl: string;
10
+ totalPages: number;
11
+ maxDepth: number;
12
+ pages: SitePage[];
13
+ /** Adjacency list: page URL -> list of linked page URLs (internal only) */
14
+ graph: Record<string, string[]>;
15
+ /** Breadcrumb / hierarchy: page URL -> parent URL (first discovered parent) */
16
+ parent: Record<string, string>;
17
+ }
18
+ /**
19
+ * Crawl a URL and build a site map of all discoverable internal pages.
20
+ *
21
+ * Uses BFS to traverse same-domain links up to `maxPages` pages.
22
+ * Respects `maxDepth` to limit how deep the crawl goes.
23
+ */
24
+ export declare function crawlSiteMap(url: string, options?: {
25
+ maxPages?: number;
26
+ maxDepth?: number;
27
+ sameDomain?: boolean;
28
+ }): Promise<SiteMap>;
29
+ /**
30
+ * Format the site map as a human-readable tree string.
31
+ */
32
+ export declare function formatSiteMap(siteMap: SiteMap): string;