xcoder-dna 0.0.0-stage → 1.3.1

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 +21 -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 +38 -3
@@ -0,0 +1,51 @@
1
+ import type { Role } from "../types.js";
2
+ /**
3
+ * Curated map from Xcoder SDLC's internal Role (see src/types.ts) to the external
4
+ * SKILL.md names (under the resolved skills directory, e.g. `skills/<name>/
5
+ * SKILL.md` at the project root) that are safe and relevant to inject for
6
+ * that role.
7
+ *
8
+ * WHY THIS EXISTS: previously, `sub-agent.ts` called `getExternalSkills()`
9
+ * directly and appended *every* external skill's one-line description to
10
+ * *every* non-conversation role's prompt, regardless of relevance. That had
11
+ * two problems:
12
+ * 1. Noise — a `tester` subtask's prompt would also see one-liners for
13
+ * AWS, Kubernetes, DFIR, business-analyst UI design, etc.
14
+ * 2. Real contradictions — some external skills share a name with a Role
15
+ * but describe a different job. The clearest case: the external
16
+ * "business-analyst" skill (traditional BRD/FRD/ERP requirements work)
17
+ * directly contradicted Xcoder SDLC's hardcoded `business-analyst` Role
18
+ * directive, which is deliberately scoped to UI/UX page design only
19
+ * (see ROLE_DIRECTIVES["business-analyst"] in ./directives.ts, and the
20
+ * separate BA_REQUIREMENTS_DIRECTIVE carved out specifically to keep
21
+ * general requirements work OUT of that Role). That skill has since
22
+ * been renamed to "enterprise-systems-analyst" and is intentionally
23
+ * NOT listed under "business-analyst" below.
24
+ *
25
+ * Keep this list conservative: only add a skill here once you've confirmed
26
+ * its guidance doesn't contradict the hardcoded ROLE_DIRECTIVES entry for
27
+ * that role. When in doubt, leave it out — an omitted skill just means one
28
+ * fewer optional hint, but a contradictory one actively confuses the model
29
+ * about what it's supposed to do.
30
+ */
31
+ export declare const ROLE_SKILL_ALLOWLIST: Partial<Record<Role, string[]>>;
32
+ export interface RoutedSkillsOptions {
33
+ skillDir?: string;
34
+ /**
35
+ * Cap on how many external skill lines get injected per subtask, so a
36
+ * role's allowlist growing over time can't unboundedly bloat the prompt.
37
+ * Default 6.
38
+ */
39
+ maxSkills?: number;
40
+ }
41
+ /**
42
+ * Role-aware replacement for calling getExternalSkills() directly. Returns
43
+ * only the external skills allowlisted for this specific role, formatted
44
+ * exactly the way getExternalSkills() already formats them ("name:
45
+ * description"), so existing callers that treat the result as a flat
46
+ * string[] keep working unchanged.
47
+ *
48
+ * Returns [] when the XCODER_EXTERNAL_SKILLS flag is off, or when the role
49
+ * has no allowlist entry (e.g. "conversation").
50
+ */
51
+ export declare function getRoutedExternalSkills(role: Role, opts?: RoutedSkillsOptions): string[];
@@ -0,0 +1,90 @@
1
+ import { isExternalSkillsEnabled, getExternalSkills } from "./externalSkillLoader.js";
2
+ /**
3
+ * Curated map from Xcoder SDLC's internal Role (see src/types.ts) to the external
4
+ * SKILL.md names (under the resolved skills directory, e.g. `skills/<name>/
5
+ * SKILL.md` at the project root) that are safe and relevant to inject for
6
+ * that role.
7
+ *
8
+ * WHY THIS EXISTS: previously, `sub-agent.ts` called `getExternalSkills()`
9
+ * directly and appended *every* external skill's one-line description to
10
+ * *every* non-conversation role's prompt, regardless of relevance. That had
11
+ * two problems:
12
+ * 1. Noise — a `tester` subtask's prompt would also see one-liners for
13
+ * AWS, Kubernetes, DFIR, business-analyst UI design, etc.
14
+ * 2. Real contradictions — some external skills share a name with a Role
15
+ * but describe a different job. The clearest case: the external
16
+ * "business-analyst" skill (traditional BRD/FRD/ERP requirements work)
17
+ * directly contradicted Xcoder SDLC's hardcoded `business-analyst` Role
18
+ * directive, which is deliberately scoped to UI/UX page design only
19
+ * (see ROLE_DIRECTIVES["business-analyst"] in ./directives.ts, and the
20
+ * separate BA_REQUIREMENTS_DIRECTIVE carved out specifically to keep
21
+ * general requirements work OUT of that Role). That skill has since
22
+ * been renamed to "enterprise-systems-analyst" and is intentionally
23
+ * NOT listed under "business-analyst" below.
24
+ *
25
+ * Keep this list conservative: only add a skill here once you've confirmed
26
+ * its guidance doesn't contradict the hardcoded ROLE_DIRECTIVES entry for
27
+ * that role. When in doubt, leave it out — an omitted skill just means one
28
+ * fewer optional hint, but a contradictory one actively confuses the model
29
+ * about what it's supposed to do.
30
+ */
31
+ export const ROLE_SKILL_ALLOWLIST = {
32
+ "requirements-analyst": ["analyst", "enterprise-systems-analyst", "task-planning"],
33
+ architect: ["architect", "software-architect", "design-patterns", "solid-principles", "project-scaffolding"],
34
+ // Deliberately does NOT include "refactorer"-flavored language — see the
35
+ // updated skills/programmer/SKILL.md description, which was itself
36
+ // narrowed to new/design-driven implementation for the same reason.
37
+ programmer: ["programmer", "software-engineer", "design-patterns", "solid-principles", "git-vcs"],
38
+ // Deliberately excludes "programmer" — that skill's original scope
39
+ // ("fix bug", "refactor") blurred the boundary Xcoder SDLC's directive draws
40
+ // between programmer (design-driven implementation) and refactorer
41
+ // (minimal-diff, no redesign). Give refactorer its own, narrower set.
42
+ refactorer: ["software-engineer", "design-patterns", "solid-principles", "rca"],
43
+ tester: ["tester", "qa-engineer", "rca", "performance-tester"],
44
+ "ui-api-tester": ["playwright-ui-tester", "qa-engineer", "ui-ux-design"],
45
+ "technical-writer": ["workspace-context"],
46
+ devops: [
47
+ "devops", "docker", "docker-expert", "kubernetes", "kubernetes-expert",
48
+ "aws", "azure", "openshift", "redhat", "rosa", "ubuntu", "git-vcs",
49
+ ],
50
+ // "conversation" intentionally omitted: sub-agent.ts already skips
51
+ // external-skill injection entirely for this role, so listing anything
52
+ // here would never be used — kept out to avoid implying otherwise.
53
+ // Intentionally does NOT include "enterprise-systems-analyst" — see the
54
+ // module doc comment above. This Role is UI/UX-scoped in Xcoder SDLC.
55
+ "business-analyst": ["ui-ux-design"],
56
+ "defect-manager": ["rca", "task-planning"],
57
+ // Deliberately excludes "scrum-master-agent" (a behavioral playbook for
58
+ // human-team sprint coaching — stand-ups, burndown, retro insights) —
59
+ // this Role is an internal JSON pass/fail quality gate, a different job,
60
+ // and it needs a strict, uncluttered prompt to reliably emit clean JSON.
61
+ "scrum-master": ["scrum-framework"],
62
+ "system-architect": ["software-architect", "design-patterns", "solid-principles"],
63
+ "security-lead": ["secops", "advanced-dfir", "ethical-hacking-methodology", "advanced-pentest-lab", "pentester"],
64
+ };
65
+ /**
66
+ * Role-aware replacement for calling getExternalSkills() directly. Returns
67
+ * only the external skills allowlisted for this specific role, formatted
68
+ * exactly the way getExternalSkills() already formats them ("name:
69
+ * description"), so existing callers that treat the result as a flat
70
+ * string[] keep working unchanged.
71
+ *
72
+ * Returns [] when the XCODER_EXTERNAL_SKILLS flag is off, or when the role
73
+ * has no allowlist entry (e.g. "conversation").
74
+ */
75
+ export function getRoutedExternalSkills(role, opts = {}) {
76
+ if (!isExternalSkillsEnabled())
77
+ return [];
78
+ const allowedNames = ROLE_SKILL_ALLOWLIST[role];
79
+ if (!allowedNames || allowedNames.length === 0)
80
+ return [];
81
+ const allowedSet = new Set(allowedNames);
82
+ const all = getExternalSkills({ skillDir: opts.skillDir }); // ["name: description", ...]
83
+ const filtered = all.filter((line) => {
84
+ const sep = line.indexOf(":");
85
+ const name = sep === -1 ? line : line.slice(0, sep);
86
+ return allowedSet.has(name);
87
+ });
88
+ const max = opts.maxSkills ?? 6;
89
+ return filtered.slice(0, max);
90
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Single source of truth for skill discovery.
3
+ *
4
+ * Before this module there were two independent `path.join(..., "skills")`
5
+ * sites (loadConfig and SkillRegistry) and neither one checked whether the
6
+ * directory it found actually contained a usable pack. An empty
7
+ * `~/.xcoder/skills` therefore *shadowed* the bundled packs and the CLI came
8
+ * up with zero skills — the bug this module exists to fix.
9
+ *
10
+ * Resolution order (first USABLE candidate wins, where usable means at least
11
+ * one pack parses as a valid SkillHeader — never a bare `existsSync`):
12
+ *
13
+ * 1. opts.skillDir (explicit; honoured even if empty)
14
+ * 2. $XCODER_HOME/skills
15
+ * 3. ~/.xcoder/skills (the fixed home location)
16
+ * 4. getAppDir()/skills (installer layout)
17
+ * 5. <exeDir>/../share/xcoder/skills (.deb / macOS / install.sh)
18
+ * 6. getAppDir()/../skills (npm dist/)
19
+ * 7. getAppDir()/../../skills (source checkout)
20
+ * 8. cwd/skills
21
+ * 9. fallback: getAppDir()
22
+ */
23
+ /** Where a resolved skills root came from, for the debug line and for tests. */
24
+ export type SkillsRootSource = "explicit" | "xcoders-home" | "user-home" | "installer" | "cwd" | "fallback";
25
+ export interface SkillsRoot {
26
+ /** Directory D such that D/skills is the skills directory. */
27
+ readonly root: string;
28
+ /** The skills directory itself (D/skills). */
29
+ readonly skillsDir: string;
30
+ readonly source: SkillsRootSource;
31
+ /** Number of packs that parsed as a valid skill header. */
32
+ readonly usableCount: number;
33
+ }
34
+ export interface ResolveSkillsRootOptions {
35
+ skillDir?: string;
36
+ homeDir?: string;
37
+ appDir?: string;
38
+ exeDir?: string;
39
+ }
40
+ /**
41
+ * Directory the app runs from. Under `bun build --compile` modules live in a
42
+ * virtual filesystem (`/$bunfs/…`, `B:\~BUN\…`), so use the folder that holds
43
+ * the executable instead — that is where the installer puts `skills/`.
44
+ */
45
+ export declare function getAppDir(): string;
46
+ /** The fixed, user-owned location new packs are seeded into: ~/.xcoder/skills. */
47
+ export declare function getUserHomeSkillsDir(homeDir?: string): string;
48
+ /**
49
+ * Count the packs in `skillsDir` that actually parse.
50
+ *
51
+ * This is the usability test that replaces `existsSync`: a directory that
52
+ * exists but holds no valid pack must not shadow a directory that does.
53
+ */
54
+ export declare function probeSkillsDir(skillsDir: string): {
55
+ count: number;
56
+ names: string[];
57
+ };
58
+ /**
59
+ * Resolve the skills root, probing each candidate in precedence order and
60
+ * returning the first one that holds at least one usable pack.
61
+ */
62
+ export declare function resolveSkillsRoot(opts?: ResolveSkillsRootOptions): SkillsRoot;
63
+ /** Test hook: drop memoised resolutions and allow the debug line again. */
64
+ export declare function resetSkillsRootCache(): void;
@@ -0,0 +1,168 @@
1
+ // xcoder:version 1 | xcoder:task task-f9cf18 | xcoder:updated 2026-11-02T16:14:29.238Z | xcoder:subtask code-st-077ea2
2
+ /**
3
+ * Single source of truth for skill discovery.
4
+ *
5
+ * Before this module there were two independent `path.join(..., "skills")`
6
+ * sites (loadConfig and SkillRegistry) and neither one checked whether the
7
+ * directory it found actually contained a usable pack. An empty
8
+ * `~/.xcoder/skills` therefore *shadowed* the bundled packs and the CLI came
9
+ * up with zero skills — the bug this module exists to fix.
10
+ *
11
+ * Resolution order (first USABLE candidate wins, where usable means at least
12
+ * one pack parses as a valid SkillHeader — never a bare `existsSync`):
13
+ *
14
+ * 1. opts.skillDir (explicit; honoured even if empty)
15
+ * 2. $XCODER_HOME/skills
16
+ * 3. ~/.xcoder/skills (the fixed home location)
17
+ * 4. getAppDir()/skills (installer layout)
18
+ * 5. <exeDir>/../share/xcoder/skills (.deb / macOS / install.sh)
19
+ * 6. getAppDir()/../skills (npm dist/)
20
+ * 7. getAppDir()/../../skills (source checkout)
21
+ * 8. cwd/skills
22
+ * 9. fallback: getAppDir()
23
+ */
24
+ import fs from "node:fs";
25
+ import os from "node:os";
26
+ import path from "node:path";
27
+ import { log } from "../util/logger.js";
28
+ import { MAX_PACK_DIRS, resolveSkillDir } from "./skill-path-guard.js";
29
+ import { parseSkillHeaderFile } from "./skill-header.js";
30
+ /**
31
+ * Directory the app runs from. Under `bun build --compile` modules live in a
32
+ * virtual filesystem (`/$bunfs/…`, `B:\~BUN\…`), so use the folder that holds
33
+ * the executable instead — that is where the installer puts `skills/`.
34
+ */
35
+ export function getAppDir() {
36
+ const dir = typeof import.meta !== "undefined" && import.meta.dirname
37
+ ? import.meta.dirname
38
+ : __dirname;
39
+ return dir.includes("$bunfs") || dir.includes("~BUN") ? path.dirname(process.execPath) : dir;
40
+ }
41
+ /** The fixed, user-owned location new packs are seeded into: ~/.xcoder/skills. */
42
+ export function getUserHomeSkillsDir(homeDir) {
43
+ const home = homeDir ?? os.homedir();
44
+ return path.join(home, ".xcoder", "skills");
45
+ }
46
+ /** Emit the one-per-process debug line naming the resolved root. */
47
+ let debugLogged = false;
48
+ function logResolvedRoot(result) {
49
+ if (debugLogged || !process.env["XCODER_DEBUG_CONFIG_PATH"])
50
+ return;
51
+ debugLogged = true;
52
+ log.dim(`skillsRoot: ${result.root} (source=${result.source}, packs=${result.usableCount})`);
53
+ }
54
+ /**
55
+ * Count the packs in `skillsDir` that actually parse.
56
+ *
57
+ * This is the usability test that replaces `existsSync`: a directory that
58
+ * exists but holds no valid pack must not shadow a directory that does.
59
+ */
60
+ export function probeSkillsDir(skillsDir) {
61
+ const names = [];
62
+ let entries;
63
+ try {
64
+ entries = fs.readdirSync(skillsDir, { withFileTypes: true });
65
+ }
66
+ catch {
67
+ return { count: 0, names };
68
+ }
69
+ let visited = 0;
70
+ for (const entry of entries) {
71
+ if (visited >= MAX_PACK_DIRS)
72
+ break;
73
+ if (!entry.isDirectory())
74
+ continue;
75
+ visited++;
76
+ const packDir = resolveSkillDir(skillsDir, entry.name);
77
+ if (!packDir)
78
+ continue;
79
+ const parsed = parseSkillHeaderFile(path.join(packDir, "SKILL.md"));
80
+ if (!parsed.ok || !parsed.header)
81
+ continue;
82
+ names.push(parsed.header.name);
83
+ }
84
+ return { count: names.length, names };
85
+ }
86
+ function buildCandidates(opts) {
87
+ const appDir = opts.appDir ?? getAppDir();
88
+ const exeDir = opts.exeDir ?? path.dirname(process.execPath);
89
+ const candidates = [];
90
+ if (process.env["XCODER_HOME"]) {
91
+ candidates.push({ root: process.env["XCODER_HOME"], source: "xcoders-home" });
92
+ }
93
+ candidates.push({
94
+ root: path.dirname(getUserHomeSkillsDir(opts.homeDir)),
95
+ source: "user-home",
96
+ });
97
+ candidates.push({ root: appDir, source: "installer" });
98
+ candidates.push({ root: path.join(exeDir, "..", "share", "xcoder"), source: "installer" });
99
+ candidates.push({ root: path.join(appDir, ".."), source: "installer" });
100
+ candidates.push({ root: path.join(appDir, "..", ".."), source: "installer" });
101
+ candidates.push({ root: process.cwd(), source: "cwd" });
102
+ return candidates;
103
+ }
104
+ /** Memoised results, keyed by the option tuple so an injected dir never aliases. */
105
+ const memo = new Map();
106
+ function memoKey(opts) {
107
+ return [
108
+ opts.skillDir ?? "\u0000",
109
+ opts.homeDir ?? "\u0000",
110
+ opts.appDir ?? "\u0000",
111
+ opts.exeDir ?? "\u0000",
112
+ process.env["XCODER_HOME"] ?? "\u0000",
113
+ process.cwd(),
114
+ ].join("\u0001");
115
+ }
116
+ /**
117
+ * Resolve the skills root, probing each candidate in precedence order and
118
+ * returning the first one that holds at least one usable pack.
119
+ */
120
+ export function resolveSkillsRoot(opts = {}) {
121
+ const key = memoKey(opts);
122
+ const cached = memo.get(key);
123
+ if (cached)
124
+ return cached;
125
+ let result;
126
+ if (opts.skillDir) {
127
+ // Explicit wins even when empty (T2): tests inject a temp dir and assert
128
+ // zero skills; silently falling back would read the developer's real dir.
129
+ const skillsDir = path.resolve(opts.skillDir);
130
+ result = {
131
+ root: path.dirname(skillsDir),
132
+ skillsDir,
133
+ source: "explicit",
134
+ usableCount: probeSkillsDir(skillsDir).count,
135
+ };
136
+ }
137
+ else {
138
+ const candidates = buildCandidates(opts);
139
+ const fallbackRoot = opts.appDir ?? getAppDir();
140
+ result = {
141
+ root: fallbackRoot,
142
+ skillsDir: path.join(fallbackRoot, "skills"),
143
+ source: "fallback",
144
+ usableCount: 0,
145
+ };
146
+ for (const candidate of candidates) {
147
+ const skillsDir = path.join(candidate.root, "skills");
148
+ const probe = probeSkillsDir(skillsDir);
149
+ if (probe.count > 0) {
150
+ result = {
151
+ root: candidate.root,
152
+ skillsDir,
153
+ source: candidate.source,
154
+ usableCount: probe.count,
155
+ };
156
+ break;
157
+ }
158
+ }
159
+ }
160
+ memo.set(key, result);
161
+ logResolvedRoot(result);
162
+ return result;
163
+ }
164
+ /** Test hook: drop memoised resolutions and allow the debug line again. */
165
+ export function resetSkillsRootCache() {
166
+ memo.clear();
167
+ debugLogged = false;
168
+ }
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: software-architect
3
+ role: architecture
4
+ description: System-level design for new services/features/migrations — explicit tradeoffs, failure-mode analysis, and documented decisions instead of implementing the first design that occurs to you.
5
+ triggers:
6
+ - "architecture"
7
+ - "design a system"
8
+ - "system design"
9
+ - "design doc"
10
+ - "how should we structure"
11
+ - "scalability"
12
+ - "microservice"
13
+ - "migrate"
14
+ - "migration plan"
15
+ - "architecture decision record"
16
+ - "tech stack"
17
+ version: "1.0.0"
18
+ requires_tools:
19
+ - read_tool
20
+ - grep_tool
21
+ - glob_tool
22
+ - write_edit_tool
23
+ composes_with:
24
+ - workspace-context
25
+ - task-planning
26
+ - software-engineer
27
+ - docker
28
+ - kubernetes
29
+ ---
30
+
31
+ ## Process
32
+
33
+ 1. Establish the actual constraints before designing: expected scale (requests/sec, data volume,
34
+ team size), consistency requirements, latency budget, and what already exists that this must
35
+ integrate with. A design without stated constraints is a guess, not an architecture.
36
+ 2. Identify 2–3 genuinely distinct approaches (not one approach and two straw men) and name the
37
+ real tradeoff each makes — write these down even in an informal design doc; "we considered X"
38
+ without the tradeoff is not useful to a future reader.
39
+ 3. Design for the failure modes, not just the happy path: what happens when a downstream service
40
+ is slow, unavailable, or returns bad data; what's the blast radius of one component failing;
41
+ what's recoverable automatically vs. needs a human.
42
+ 4. Draw the boundary between services/modules along data ownership and change-rate, not
43
+ convenience — two things that change together for unrelated reasons are a sign of a missing
44
+ boundary; two things that always change together are a sign of an unnecessary one.
45
+ 5. Record the decision (an ADR-style note: context, options considered, decision, consequences) so
46
+ the reasoning survives past the current conversation — a design that only exists as an
47
+ unexplained set of files is a maintenance liability.
48
+
49
+ ## Instructions — non-negotiable
50
+
51
+ - Never propose a distributed/microservices architecture to solve a problem a monolith handles
52
+ fine — the complexity cost (network calls, partial failure, deployment coordination) needs to be
53
+ justified by an actual scaling or team-boundary need, not defaulted to.
54
+ - State the consistency model explicitly for any design involving more than one data store
55
+ (eventual vs. strong, and what happens during the inconsistency window) — "it'll sync eventually"
56
+ without specifying how is not a complete design.
57
+ - Any design that introduces a new external dependency (a new database, queue, cloud service)
58
+ should name what it replaces or what it enables that wasn't possible before — dependencies are
59
+ not free.
60
+
61
+ ## Strategies
62
+
63
+ - Prefer boring, well-understood technology for the parts of the system that aren't the actual
64
+ differentiator — save novel/complex choices for where they earn their keep.
65
+ - Design for the current known scale plus a reasonable margin, not for a hypothetical 100x that may
66
+ never materialize — premature scaling design has a real cost in complexity today.
67
+ - When a migration is involved, design the rollback path with the same rigor as the forward path —
68
+ "we'll just roll back if it fails" is not a plan unless you've specified how.
69
+
70
+ ## Experience
71
+
72
+ - The most common architecture failure isn't picking the wrong technology, it's an unstated
73
+ assumption about consistency, ownership, or failure handling that only surfaces in production —
74
+ make those assumptions explicit in the design doc even when they seem obvious.
75
+ - Boundaries that map to team/ownership structure tend to survive; boundaries that only reflect a
76
+ snapshot of current code organization tend to get redrawn — factor in who will maintain each
77
+ piece, not just how the code happens to be organized today.
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: software-engineer
3
+ role: engineering
4
+ description: General software engineering discipline for implementation tasks — small verifiable changes, tests before/alongside code, and code that's ready for review rather than "it ran once on my machine."
5
+ triggers:
6
+ - "implement"
7
+ - "write code"
8
+ - "fix the bug"
9
+ - "fix a bug"
10
+ - "refactor"
11
+ - "add a feature"
12
+ - "code review"
13
+ - "write a function"
14
+ - "write tests"
15
+ version: "1.0.0"
16
+ requires_tools:
17
+ - read_tool
18
+ - write_edit_tool
19
+ - grep_tool
20
+ - glob_tool
21
+ - run_command_tool
22
+ composes_with:
23
+ - workspace-context
24
+ - task-planning
25
+ - software-architect
26
+ - qa-engineer
27
+ - git-vcs
28
+ ---
29
+
30
+ ## Process
31
+
32
+ 1. Read the surrounding code before writing any — match existing patterns (naming, error handling,
33
+ module structure) rather than introducing a new style for one change. `grep_tool`/`glob_tool`
34
+ for how similar things are already done in this codebase before assuming a convention.
35
+ 2. Make the smallest change that correctly solves the stated problem. A "fix the bug" task is not
36
+ an invitation to also refactor unrelated code nearby — that inflates the diff, makes review
37
+ harder, and increases the chance of an unrelated regression.
38
+ 3. Write or update a test alongside the change, not after being asked. If the codebase has a test
39
+ framework, use it; if not, at minimum verify manually via `run_command_tool` and say so.
40
+ 4. Run the actual test/build/lint commands this project uses (check `package.json` scripts,
41
+ `Makefile`, or CI config for the real invocation) before declaring the task done — "should work"
42
+ is not verification.
43
+ 5. Handle errors explicitly. Don't swallow exceptions silently, don't return null/undefined for a
44
+ failure case without the caller having a way to detect it, and don't add a broad try/catch
45
+ whose only effect is hiding a bug you haven't diagnosed.
46
+
47
+ ## Instructions — non-negotiable
48
+
49
+ - Never leave `console.log`/`print` debugging statements, commented-out old code, or TODO markers
50
+ for the exact thing you were asked to do (as opposed to genuinely out-of-scope follow-up work).
51
+ - Match existing naming/formatting conventions exactly — don't introduce camelCase into a
52
+ snake_case codebase or vice versa for "personal preference" reasons.
53
+ - Never silently change a public function's signature or behavior that other code depends on
54
+ without updating every call site — `grep_tool` for all usages first.
55
+ - If a fix reveals the same bug pattern exists elsewhere, say so explicitly rather than silently
56
+ fixing only the one instance mentioned — but don't silently fix the others without flagging it.
57
+
58
+ ## Strategies
59
+
60
+ - Prefer pure functions and explicit data flow over shared mutable state when adding new code —
61
+ easier to test, easier for the next person (or the next agent run) to reason about.
62
+ - When two implementation approaches are both reasonable, prefer the one that's more consistent
63
+ with the rest of the codebase over the one that's abstractly "better," unless the task is
64
+ specifically about improving that pattern.
65
+ - If a task is ambiguous about behavior at an edge case, pick the interpretation consistent with
66
+ how the rest of the system handles similar edge cases, and state the assumption.
67
+
68
+ ## Experience
69
+
70
+ - The most common real defect in agent-authored code is an untested edge case discovered by the
71
+ next reviewer, not a syntax error — the fix is deliberately testing boundaries (empty input,
72
+ null, zero, max values, concurrent access) rather than only the example given in the task.
73
+ - Large, unfocused diffs get rejected in review more often than small correct ones — resist the
74
+ urge to "clean up while I'm in here" unless asked.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: solid-principles
3
+ role: Software Architect / OOP Design Specialist
4
+ description: >
5
+ Reference guide to the five SOLID object-oriented design principles (Single Responsibility,
6
+ Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion), complete with
7
+ directives, violation signs, and fix patterns. Load whenever reviewing class or module design,
8
+ refactoring coupled code, or evaluating adherence to clean OOP design principles.
9
+ triggers: [solid, "solid principles", "single responsibility", "open closed", "liskov substitution", "interface segregation", "dependency inversion", decouple, refactor, "oop design"]
10
+ version: 1.0
11
+ requires_tools: [read_tool, grep_tool]
12
+ composes_with: [programmer, software-engineer, architect, rca]
13
+ ---
14
+
15
+ # SOLID Principles
16
+
17
+ A quick-reference guide to the five SOLID principles, each with a directive, signs of violation, and how to fix it.
18
+
19
+ ## How to use this skill
20
+
21
+ 1. If the user names a specific principle, explain the directive and apply it to their code/problem.
22
+ 2. If the user pastes code and asks for a review, scan it against the **violation signs** for each principle and flag the ones that apply.
23
+ 3. If the user describes a design problem, use the **Quick Decision Guide** to match the symptom to the principle that addresses it.
24
+ 4. Don't force all five onto every review — flag what's genuinely relevant, and note tradeoffs (see **General Directives**).
25
+
26
+ ---
27
+
28
+ ## S — Single Responsibility Principle
29
+ **Directive:** A class/module should have only one reason to change.
30
+ **Violation signs:**
31
+ - A class does unrelated things (e.g. a `User` class that also handles email sending and database persistence).
32
+ - Changing one feature risks breaking unrelated functionality.
33
+ - The class name is vague or joined with "and" (`ReportGeneratorAndEmailer`).
34
+ **Fix:** Split responsibilities into separate classes, each owning one concern; compose them where needed.
35
+
36
+ ---
37
+
38
+ ## O — Open/Closed Principle
39
+ **Directive:** Classes should be open for extension, but closed for modification.
40
+ **Violation signs:**
41
+ - Adding a new case means editing an existing class's internals (e.g. a growing `if/elif` or `switch` chain on type).
42
+ - Every new feature touches the same core file, risking regressions in unrelated cases.
43
+ **Fix:** Extract the varying behavior behind an interface/abstract class, and add new behavior via new subclasses or implementations instead of editing existing code (Strategy or Factory patterns often apply here).
44
+
45
+ ---
46
+
47
+ ## L — Liskov Substitution Principle
48
+ **Directive:** Subtypes must be substitutable for their base types without breaking correctness.
49
+ **Violation signs:**
50
+ - A subclass overrides a method to throw an exception, do nothing, or narrow what the base type promised.
51
+ - Client code checks the concrete type before calling a method (`if isinstance(x, SubclassY)`).
52
+ - Classic example: `Square extends Rectangle` breaks if `setWidth`/`setHeight` are independent in the base class.
53
+ **Fix:** Make sure a subclass honors the base class's contract (preconditions no stronger, postconditions no weaker). If it can't, it shouldn't be a subclass — reach for composition or a shared interface instead.
54
+
55
+ ---
56
+
57
+ ## I — Interface Segregation Principle
58
+ **Directive:** Clients shouldn't be forced to depend on methods they don't use.
59
+ **Violation signs:**
60
+ - A large "fat" interface where implementers must stub out irrelevant methods (`throw new NotImplementedException()`).
61
+ - Changing one method's signature forces recompiling/retesting classes that never use it.
62
+ **Fix:** Split large interfaces into smaller, role-specific ones; classes implement only the interfaces relevant to them.
63
+
64
+ ---
65
+
66
+ ## D — Dependency Inversion Principle
67
+ **Directive:** Depend on abstractions, not concrete implementations. High-level modules shouldn't depend on low-level modules — both should depend on abstractions.
68
+ **Violation signs:**
69
+ - A high-level class directly instantiates a low-level class (`new MySqlDatabase()` inside business logic).
70
+ - Swapping an implementation (e.g. database, payment provider) requires editing high-level code.
71
+ - Hard to unit test because dependencies can't be mocked.
72
+ **Fix:** Introduce an interface/abstract class between layers; inject the concrete implementation from outside (constructor/dependency injection) rather than instantiating it inline.
73
+
74
+ ---
75
+
76
+ ## Quick Decision Guide
77
+
78
+ | Symptom | Principle Violated |
79
+ |---|---|
80
+ | Class does too many unrelated things | Single Responsibility |
81
+ | Adding a feature means editing existing code everywhere | Open/Closed |
82
+ | Subclass breaks behavior the base class promised | Liskov Substitution |
83
+ | Class forced to implement methods it doesn't need | Interface Segregation |
84
+ | Business logic tightly coupled to a concrete implementation | Dependency Inversion |
85
+ | Hard to unit test due to hardcoded dependencies | Dependency Inversion |
86
+ | Growing if/else or switch on type | Open/Closed |
87
+
88
+ ---
89
+
90
+ ## General Directives
91
+ - SOLID principles are guidelines, not laws — over-applying them (e.g. an interface for every single class) can add needless indirection. Weigh the cost of abstraction against the actual likelihood of change.
92
+ - SRP and ISP both fight bloat — SRP at the class level, ISP at the interface level.
93
+ - OCP and DIP work together: depending on abstractions (DIP) is usually what *lets* you extend without modifying (OCP).
94
+ - When reviewing code, prioritize violations that cause real pain (hard to test, hard to extend, fragile on change) over theoretical purity.