wicked-garden 12.27.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 (640) hide show
  1. package/.claude-plugin/archetypes.json +166 -0
  2. package/.claude-plugin/components.json +75 -0
  3. package/.claude-plugin/marketplace.json +15 -0
  4. package/.claude-plugin/plugin.json +174 -0
  5. package/.claude-plugin/specialist.json +48 -0
  6. package/.claude-plugin/stack-registry.json +96 -0
  7. package/AGENTS.md +13 -0
  8. package/CHANGELOG.md +712 -0
  9. package/CONTRIBUTING.md +99 -0
  10. package/ETHOS.md +83 -0
  11. package/LICENSE +21 -0
  12. package/README.md +115 -0
  13. package/WICKED_GARDEN_BUS_EVENTS.md +149 -0
  14. package/agents/agentic/architect.md +449 -0
  15. package/agents/agentic/performance-analyst.md +702 -0
  16. package/agents/agentic/safety-reviewer.md +662 -0
  17. package/agents/crew/implementer.md +163 -0
  18. package/agents/crew/researcher.md +94 -0
  19. package/agents/crew/reviewer.md +184 -0
  20. package/agents/data/data-engineer.md +227 -0
  21. package/agents/engineering/api-documentarian.md +440 -0
  22. package/agents/engineering/migration-engineer.md +301 -0
  23. package/agents/engineering/solution-architect.md +208 -0
  24. package/agents/jam/brainstorm-facilitator.md +297 -0
  25. package/agents/jam/council.md +322 -0
  26. package/agents/jam/quick-facilitator.md +85 -0
  27. package/agents/persona/persona-agent.md +121 -0
  28. package/agents/platform/compliance-officer.md +266 -0
  29. package/agents/platform/privacy-expert.md +496 -0
  30. package/agents/platform/security-engineer.md +287 -0
  31. package/agents/product/a11y-expert.md +323 -0
  32. package/agents/product/requirements-analyst.md +238 -0
  33. package/agents/product/ui-reviewer.md +180 -0
  34. package/agents/product/ux-designer.md +199 -0
  35. package/agents/product/value-strategist.md +269 -0
  36. package/agents/qe/semantic-reviewer.md +78 -0
  37. package/commands/agentic/audit.md +24 -0
  38. package/commands/agentic/design.md +24 -0
  39. package/commands/agentic/frameworks.md +25 -0
  40. package/commands/agentic/review.md +27 -0
  41. package/commands/archetype/build.md +12 -0
  42. package/commands/archetype/decide.md +12 -0
  43. package/commands/archetype/explore.md +12 -0
  44. package/commands/archetype/incident.md +12 -0
  45. package/commands/archetype/migrate.md +12 -0
  46. package/commands/archetype/modernize.md +12 -0
  47. package/commands/archetype/review.md +14 -0
  48. package/commands/archetype/ship.md +12 -0
  49. package/commands/archetype/specify.md +12 -0
  50. package/commands/archetype/triage.md +12 -0
  51. package/commands/compile.md +37 -0
  52. package/commands/data/analyze.md +18 -0
  53. package/commands/data/data.md +21 -0
  54. package/commands/data/ml.md +18 -0
  55. package/commands/data/ontology.md +22 -0
  56. package/commands/data/pipeline.md +17 -0
  57. package/commands/deliberate.md +181 -0
  58. package/commands/engineering/add-field.md +77 -0
  59. package/commands/engineering/apply.md +58 -0
  60. package/commands/engineering/arch.md +26 -0
  61. package/commands/engineering/debug.md +27 -0
  62. package/commands/engineering/docs.md +27 -0
  63. package/commands/engineering/new-generator.md +257 -0
  64. package/commands/engineering/patch-plan.md +59 -0
  65. package/commands/engineering/plan.md +29 -0
  66. package/commands/engineering/remove.md +48 -0
  67. package/commands/engineering/rename.md +44 -0
  68. package/commands/engineering/review.md +32 -0
  69. package/commands/help.md +128 -0
  70. package/commands/install.md +118 -0
  71. package/commands/intent.md +54 -0
  72. package/commands/jam/brainstorm.md +37 -0
  73. package/commands/jam/council.md +49 -0
  74. package/commands/jam/quick.md +21 -0
  75. package/commands/jam/revisit.md +79 -0
  76. package/commands/persona/as.md +136 -0
  77. package/commands/persona/define.md +24 -0
  78. package/commands/persona/list.md +118 -0
  79. package/commands/platform/actions.md +20 -0
  80. package/commands/platform/assert.md +18 -0
  81. package/commands/platform/audit.md +23 -0
  82. package/commands/platform/compliance.md +20 -0
  83. package/commands/platform/gh.md +22 -0
  84. package/commands/platform/health.md +22 -0
  85. package/commands/platform/incident.md +23 -0
  86. package/commands/platform/infra.md +24 -0
  87. package/commands/platform/peer-health.md +103 -0
  88. package/commands/platform/plugin-health.md +58 -0
  89. package/commands/platform/security.md +38 -0
  90. package/commands/platform/toolchain.md +96 -0
  91. package/commands/platform/traces.md +20 -0
  92. package/commands/product/a11y.md +19 -0
  93. package/commands/product/acceptance.md +19 -0
  94. package/commands/product/align.md +20 -0
  95. package/commands/product/analyze.md +23 -0
  96. package/commands/product/elicit.md +19 -0
  97. package/commands/product/listen.md +24 -0
  98. package/commands/product/mockup.md +20 -0
  99. package/commands/product/screenshot.md +19 -0
  100. package/commands/product/strategy.md +40 -0
  101. package/commands/product/synthesize.md +23 -0
  102. package/commands/product/ux-review.md +42 -0
  103. package/commands/product/ux.md +20 -0
  104. package/commands/product/visual-direction.md +34 -0
  105. package/commands/prove.md +47 -0
  106. package/commands/report-issue.md +243 -0
  107. package/commands/reset.md +144 -0
  108. package/commands/search/blast-radius.md +58 -0
  109. package/commands/search/hotspots.md +55 -0
  110. package/commands/search/index.md +38 -0
  111. package/commands/search/lineage.md +47 -0
  112. package/commands/search/service-map.md +79 -0
  113. package/commands/setup.md +363 -0
  114. package/commands/smaht/briefing.md +200 -0
  115. package/commands/smaht/events-import.md +95 -0
  116. package/commands/smaht/state.md +19 -0
  117. package/commands/where-am-i.md +58 -0
  118. package/docs/README.md +32 -0
  119. package/docs/adr/0001-code-relationship-graph-engine.md +116 -0
  120. package/docs/adr/0002-major-cleanup-keep-cut.md +91 -0
  121. package/docs/adr/0003-peers-gate-required-layers-optin.md +41 -0
  122. package/docs/adr/0004-code-graph-moves-to-wicked-brain.md +47 -0
  123. package/docs/brain-chunk-format.md +135 -0
  124. package/docs/compiler.md +95 -0
  125. package/docs/daemon-api.md +70 -0
  126. package/docs/domains.md +197 -0
  127. package/docs/getting-started.md +208 -0
  128. package/docs/plans/2026-06-08-wicked-loom-conduct.md +1337 -0
  129. package/docs/plans/2026-06-08-wicked-loom-contract.md +638 -0
  130. package/docs/plans/2026-06-08-wicked-loom-cutover.md +1300 -0
  131. package/docs/plans/2026-06-08-wicked-loom-expand-compose.md +843 -0
  132. package/docs/plans/2026-06-08-wicked-loom-flow-cutover.md +403 -0
  133. package/docs/plans/2026-06-10-codegraph-to-brain-phase1a-graph-core.md +838 -0
  134. package/docs/plans/2026-06-10-codegraph-to-brain-phase1b-injected-edges.md +44 -0
  135. package/docs/required-peers.md +60 -0
  136. package/docs/specs/2026-06-08-wicked-loom-extraction.md +225 -0
  137. package/docs/specs/2026-06-10-codegraph-to-brain-migration.md +168 -0
  138. package/docs/v11/archetypes.md +231 -0
  139. package/hooks/hooks.json +275 -0
  140. package/hooks/scripts/bootstrap.py +1797 -0
  141. package/hooks/scripts/invoke.py +62 -0
  142. package/hooks/scripts/notification.py +166 -0
  143. package/hooks/scripts/permission_request.py +223 -0
  144. package/hooks/scripts/post_tool.py +1374 -0
  145. package/hooks/scripts/pre_compact.py +272 -0
  146. package/hooks/scripts/pre_tool.py +1278 -0
  147. package/hooks/scripts/prompt_submit.py +1109 -0
  148. package/hooks/scripts/session_end.py +95 -0
  149. package/hooks/scripts/stop.py +624 -0
  150. package/hooks/scripts/subagent_lifecycle.py +464 -0
  151. package/hooks/scripts/subscribers/on_gate_decided.py +84 -0
  152. package/hooks/scripts/task_completed.py +322 -0
  153. package/hooks/scripts/worktree_guard.py +148 -0
  154. package/hooks/subscriptions/on_gate_decided.json +9 -0
  155. package/install.mjs +128 -0
  156. package/package.json +41 -0
  157. package/pyproject.toml +59 -0
  158. package/schemas/README.md +32 -0
  159. package/schemas/assert_contracts.json +37 -0
  160. package/schemas/health_probe.json +46 -0
  161. package/schemas/plugin_status.json +37 -0
  162. package/scripts/_adapters/__init__.py +166 -0
  163. package/scripts/_adapters/jira_adapter.py +18 -0
  164. package/scripts/_adapters/linear_adapter.py +18 -0
  165. package/scripts/_adapters/miro_adapter.py +18 -0
  166. package/scripts/_adapters/notion_adapter.py +18 -0
  167. package/scripts/_agents.py +357 -0
  168. package/scripts/_brain_ingest/__init__.py +2 -0
  169. package/scripts/_brain_ingest/session_fact_extractor.py +341 -0
  170. package/scripts/_brain_port.py +163 -0
  171. package/scripts/_bus.py +1081 -0
  172. package/scripts/_bus_catalog_gen.py +93 -0
  173. package/scripts/_bus_consumers.json +46 -0
  174. package/scripts/_bus_emit.py +43 -0
  175. package/scripts/_capability_registry.py +334 -0
  176. package/scripts/_capability_resolver.py +322 -0
  177. package/scripts/_domain_store.py +559 -0
  178. package/scripts/_event_log_reader.py +154 -0
  179. package/scripts/_event_schema.py +305 -0
  180. package/scripts/_event_store.py +397 -0
  181. package/scripts/_heavy_cadence.py +324 -0
  182. package/scripts/_integration_resolver.py +321 -0
  183. package/scripts/_logger.py +151 -0
  184. package/scripts/_loom.py +482 -0
  185. package/scripts/_paths.py +133 -0
  186. package/scripts/_python.sh +22 -0
  187. package/scripts/_run.py +137 -0
  188. package/scripts/_session.py +502 -0
  189. package/scripts/_validate_registry.py +1042 -0
  190. package/scripts/_wicked_testing_probe.py +277 -0
  191. package/scripts/agentic/analyze_agents.py +391 -0
  192. package/scripts/agentic/detect_framework.py +420 -0
  193. package/scripts/agentic/issue_taxonomy.py +357 -0
  194. package/scripts/agentic/pattern_scorer.py +434 -0
  195. package/scripts/classify/persist.py +169 -0
  196. package/scripts/compiler/compile.py +552 -0
  197. package/scripts/compiler/phase0/VERDICT.md +60 -0
  198. package/scripts/compiler/phase0/detect.py +292 -0
  199. package/scripts/compiler/phase0/emit.py +228 -0
  200. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.bindings.json +30 -0
  201. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.lint-output.txt +17 -0
  202. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/.wg/evidence/failing-tests.txt +4 -0
  203. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/.wg/evidence/honest-tests.txt +2 -0
  204. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/fab-fail.build.md +8 -0
  205. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/fab-missing.build.md +8 -0
  206. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/honest.build.md +8 -0
  207. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/wg_check_claims.py +174 -0
  208. package/scripts/compiler/phase0/evidence/command_iq.bindings.json +45 -0
  209. package/scripts/compiler/phase0/evidence/command_iq.lint-output.txt +17 -0
  210. package/scripts/compiler/phase0/evidence/command_iq.stage/.projects/evidence-domain/phase-1-clarify/evidence/failing-tests.txt +4 -0
  211. package/scripts/compiler/phase0/evidence/command_iq.stage/.projects/evidence-domain/phase-1-clarify/evidence/honest-tests.txt +3 -0
  212. package/scripts/compiler/phase0/evidence/command_iq.stage/fab-fail.build.md +8 -0
  213. package/scripts/compiler/phase0/evidence/command_iq.stage/fab-missing.build.md +8 -0
  214. package/scripts/compiler/phase0/evidence/command_iq.stage/honest.build.md +8 -0
  215. package/scripts/compiler/phase0/evidence/command_iq.stage/wg_check_claims.py +174 -0
  216. package/scripts/compiler/phase0/evidence/memos.bindings.json +28 -0
  217. package/scripts/compiler/phase0/evidence/memos.lint-output.txt +17 -0
  218. package/scripts/compiler/phase0/evidence/memos.stage/.wg/evidence/failing-tests.txt +4 -0
  219. package/scripts/compiler/phase0/evidence/memos.stage/.wg/evidence/honest-tests.txt +2 -0
  220. package/scripts/compiler/phase0/evidence/memos.stage/fab-fail.build.md +8 -0
  221. package/scripts/compiler/phase0/evidence/memos.stage/fab-missing.build.md +8 -0
  222. package/scripts/compiler/phase0/evidence/memos.stage/honest.build.md +8 -0
  223. package/scripts/compiler/phase0/evidence/memos.stage/wg_check_claims.py +174 -0
  224. package/scripts/compiler/phase0/evidence/verdict.json +104 -0
  225. package/scripts/compiler/phase0/evidence/wicked-bus.bindings.json +29 -0
  226. package/scripts/compiler/phase0/evidence/wicked-bus.lint-output.txt +17 -0
  227. package/scripts/compiler/phase0/evidence/wicked-bus.stage/coverage/failing-tests.txt +4 -0
  228. package/scripts/compiler/phase0/evidence/wicked-bus.stage/coverage/honest-tests.txt +3 -0
  229. package/scripts/compiler/phase0/evidence/wicked-bus.stage/fab-fail.build.md +8 -0
  230. package/scripts/compiler/phase0/evidence/wicked-bus.stage/fab-missing.build.md +8 -0
  231. package/scripts/compiler/phase0/evidence/wicked-bus.stage/honest.build.md +8 -0
  232. package/scripts/compiler/phase0/evidence/wicked-bus.stage/wg_check_claims.py +174 -0
  233. package/scripts/compiler/phase0/evidence/wire-vault-transcript.txt +60 -0
  234. package/scripts/compiler/phase0/run_probe.py +234 -0
  235. package/scripts/compiler/phase0/wire_vault.py +310 -0
  236. package/scripts/crew/__init__.py +0 -0
  237. package/scripts/crew/_task_audit_writer.py +243 -0
  238. package/scripts/crew/_task_reader.py +389 -0
  239. package/scripts/crew/archetypes_v11.py +348 -0
  240. package/scripts/crew/detectors/__init__.py +12 -0
  241. package/scripts/crew/flow_compiler.py +121 -0
  242. package/scripts/crew/phase_manager.py +703 -0
  243. package/scripts/crew/scope_delta.py +264 -0
  244. package/scripts/crew/specialist_resolver.py +218 -0
  245. package/scripts/crew/stack_registry.py +189 -0
  246. package/scripts/data/data_profiler.py +271 -0
  247. package/scripts/data/ontology_recommender.py +231 -0
  248. package/scripts/data/schema_validator.py +267 -0
  249. package/scripts/delivery/drift.py +739 -0
  250. package/scripts/delivery/telemetry.py +614 -0
  251. package/scripts/engineering/patch/codegraph_db.py +125 -0
  252. package/scripts/engineering/patch/generators/__init__.py +56 -0
  253. package/scripts/engineering/patch/generators/base.py +373 -0
  254. package/scripts/engineering/patch/generators/csharp_generator.py +494 -0
  255. package/scripts/engineering/patch/generators/go_generator.py +430 -0
  256. package/scripts/engineering/patch/generators/java_generator.py +928 -0
  257. package/scripts/engineering/patch/generators/jsp_generator.py +454 -0
  258. package/scripts/engineering/patch/generators/kotlin_generator.py +561 -0
  259. package/scripts/engineering/patch/generators/perl_generator.py +510 -0
  260. package/scripts/engineering/patch/generators/php_generator.py +644 -0
  261. package/scripts/engineering/patch/generators/propagation_engine.py +929 -0
  262. package/scripts/engineering/patch/generators/python_generator.py +487 -0
  263. package/scripts/engineering/patch/generators/ruby_generator.py +463 -0
  264. package/scripts/engineering/patch/generators/rust_generator.py +400 -0
  265. package/scripts/engineering/patch/generators/sql_generator.py +594 -0
  266. package/scripts/engineering/patch/generators/typescript_generator.py +439 -0
  267. package/scripts/engineering/patch/patch.py +800 -0
  268. package/scripts/engineering/patch/safety.py +429 -0
  269. package/scripts/jam/__init__.py +0 -0
  270. package/scripts/jam/_bus_consumers.py +271 -0
  271. package/scripts/jam/agentic_cli_registry.py +703 -0
  272. package/scripts/jam/consensus.py +737 -0
  273. package/scripts/jam/detect_clis.py +409 -0
  274. package/scripts/jam/jam.py +283 -0
  275. package/scripts/jam/save_transcript.py +171 -0
  276. package/scripts/loom/__init__.py +22 -0
  277. package/scripts/loom/cli.py +170 -0
  278. package/scripts/loom/compose.py +180 -0
  279. package/scripts/loom/gate.py +120 -0
  280. package/scripts/loom/manifest.py +140 -0
  281. package/scripts/loom/resolve.py +59 -0
  282. package/scripts/persona/__init__.py +0 -0
  283. package/scripts/persona/registry.py +688 -0
  284. package/scripts/platform/guard_pipeline.py +1214 -0
  285. package/scripts/platform/guard_profiles.py +216 -0
  286. package/scripts/platform/observability/assert_contracts.py +434 -0
  287. package/scripts/platform/observability/health_probe.py +915 -0
  288. package/scripts/platform/observability/ops_log_viewer.py +209 -0
  289. package/scripts/platform/prereq_doctor.py +567 -0
  290. package/scripts/qe/conditions_manifest.py +260 -0
  291. package/scripts/qe/content_sanitizer.py +160 -0
  292. package/scripts/qe/coverage_tracker.py +535 -0
  293. package/scripts/qe/discover_scenarios.py +243 -0
  294. package/scripts/qe/evidence_tracker.py +232 -0
  295. package/scripts/qe/prove.py +196 -0
  296. package/scripts/qe/registry_lookup.py +80 -0
  297. package/scripts/qe/registry_store.py +176 -0
  298. package/scripts/qe/semantic_review.py +1005 -0
  299. package/scripts/qe/vault_gate.py +382 -0
  300. package/scripts/qe/verdict_audit.py +175 -0
  301. package/scripts/qe/verdict_schema.py +335 -0
  302. package/scripts/reset.py +220 -0
  303. package/scripts/resolve_path.py +22 -0
  304. package/scripts/sentinel/invariants.py +402 -0
  305. package/scripts/sentinel/pre_push.py +73 -0
  306. package/scripts/setup/__init__.py +1 -0
  307. package/scripts/setup/detect_state.py +114 -0
  308. package/scripts/setup/migrate_legacy.py +67 -0
  309. package/scripts/setup/migrate_v6_projects.py +232 -0
  310. package/scripts/setup/onboarding.py +114 -0
  311. package/scripts/smaht/_bus_consumers.py +98 -0
  312. package/scripts/smaht/adapters/__init__.py +83 -0
  313. package/scripts/smaht/adapters/brain_adapter.py +254 -0
  314. package/scripts/smaht/adapters/context7_adapter.py +438 -0
  315. package/scripts/smaht/adapters/delegation_adapter.py +104 -0
  316. package/scripts/smaht/adapters/domain_adapter.py +206 -0
  317. package/scripts/smaht/adapters/events_adapter.py +231 -0
  318. package/scripts/smaht/adapters/tools_adapter.py +49 -0
  319. package/scripts/smaht/cheatsheet_store.py +236 -0
  320. package/scripts/smaht/context_package.py +386 -0
  321. package/scripts/smaht/knowledge_graph.py +395 -0
  322. package/scripts/smaht/propose_skills.py +856 -0
  323. package/scripts/smaht/test_cheatsheet_store.py +428 -0
  324. package/scripts/statusline.py +151 -0
  325. package/scripts/where_am_i.py +236 -0
  326. package/skills/agentic/agentic-patterns/SKILL.md +91 -0
  327. package/skills/agentic/agentic-patterns/refs/anti-patterns-design.md +283 -0
  328. package/skills/agentic/agentic-patterns/refs/anti-patterns-operational.md +216 -0
  329. package/skills/agentic/agentic-patterns/refs/pattern-catalog.md +329 -0
  330. package/skills/agentic/context-engineering/SKILL.md +142 -0
  331. package/skills/agentic/context-engineering/refs/caching-and-optimization.md +251 -0
  332. package/skills/agentic/context-engineering/refs/compression-techniques.md +171 -0
  333. package/skills/agentic/context-engineering/refs/cost-calculation-budget.md +250 -0
  334. package/skills/agentic/context-engineering/refs/cost-optimization-reporting.md +300 -0
  335. package/skills/agentic/context-engineering/refs/selective-loading.md +179 -0
  336. package/skills/agentic/frameworks/SKILL.md +191 -0
  337. package/skills/agentic/frameworks/refs/framework-profiles-1.md +209 -0
  338. package/skills/agentic/frameworks/refs/framework-profiles-2.md +214 -0
  339. package/skills/agentic/frameworks/refs/migration-patterns-paths.md +267 -0
  340. package/skills/agentic/frameworks/refs/migration-patterns-testing.md +208 -0
  341. package/skills/agentic/refs/audit.md +134 -0
  342. package/skills/agentic/refs/design.md +137 -0
  343. package/skills/agentic/refs/frameworks.md +102 -0
  344. package/skills/agentic/refs/review.md +160 -0
  345. package/skills/agentic/review-methodology/SKILL.md +186 -0
  346. package/skills/agentic/review-methodology/refs/deliverable-templates.md +246 -0
  347. package/skills/agentic/review-methodology/refs/issue-taxonomy-quality-testing.md +277 -0
  348. package/skills/agentic/review-methodology/refs/issue-taxonomy-reliability-safety.md +253 -0
  349. package/skills/agentic/trust-and-safety/SKILL.md +177 -0
  350. package/skills/agentic/trust-and-safety/refs/guardrails-actions.md +246 -0
  351. package/skills/agentic/trust-and-safety/refs/guardrails-input-output.md +238 -0
  352. package/skills/agentic/trust-and-safety/refs/guardrails-resources.md +209 -0
  353. package/skills/agentic/trust-and-safety/refs/safety-checklist-advanced.md +209 -0
  354. package/skills/agentic/trust-and-safety/refs/safety-checklist-core.md +215 -0
  355. package/skills/archetype/SKILL.md +104 -0
  356. package/skills/archetype/refs/build.md +142 -0
  357. package/skills/archetype/refs/decide.md +117 -0
  358. package/skills/archetype/refs/explore.md +66 -0
  359. package/skills/archetype/refs/incident.md +149 -0
  360. package/skills/archetype/refs/migrate.md +170 -0
  361. package/skills/archetype/refs/modernize.md +187 -0
  362. package/skills/archetype/refs/review.md +145 -0
  363. package/skills/archetype/refs/ship.md +117 -0
  364. package/skills/archetype/refs/specify.md +108 -0
  365. package/skills/archetype/refs/triage.md +62 -0
  366. package/skills/classify/SKILL.md +157 -0
  367. package/skills/data/analysis/SKILL.md +125 -0
  368. package/skills/data/analysis/refs/templates.md +170 -0
  369. package/skills/data/data/SKILL.md +118 -0
  370. package/skills/data/data/refs/examples.md +235 -0
  371. package/skills/data/ml/SKILL.md +125 -0
  372. package/skills/data/ml/refs/templates.md +172 -0
  373. package/skills/data/pipeline/SKILL.md +136 -0
  374. package/skills/data/pipeline/refs/templates.md +175 -0
  375. package/skills/data/refs/analyze.md +123 -0
  376. package/skills/data/refs/data.md +95 -0
  377. package/skills/data/refs/ml.md +118 -0
  378. package/skills/data/refs/pipeline.md +92 -0
  379. package/skills/deliberate/SKILL.md +125 -0
  380. package/skills/deliberate/refs/architecture-lens.md +37 -0
  381. package/skills/deliberate/refs/assumptions-lens.md +43 -0
  382. package/skills/deliberate/refs/code-lens.md +38 -0
  383. package/skills/deliberate/refs/content-lens.md +37 -0
  384. package/skills/deliberate/refs/data-lens.md +43 -0
  385. package/skills/deliberate/refs/design-lens.md +37 -0
  386. package/skills/deliberate/refs/opportunity-patterns.md +107 -0
  387. package/skills/deliberate/refs/ops-lens.md +43 -0
  388. package/skills/deliberate/refs/product-lens.md +46 -0
  389. package/skills/deliberate/refs/rethink-framework.md +77 -0
  390. package/skills/deliberate/refs/security-lens.md +47 -0
  391. package/skills/deliberate/refs/testing-lens.md +45 -0
  392. package/skills/deliberate/refs/timing-lens.md +42 -0
  393. package/skills/engineering/architecture/SKILL.md +177 -0
  394. package/skills/engineering/architecture/refs/adr-template.md +268 -0
  395. package/skills/engineering/architecture/refs/architecture-template-deployment.md +176 -0
  396. package/skills/engineering/architecture/refs/architecture-template-design.md +300 -0
  397. package/skills/engineering/architecture/refs/examples-ecommerce-analytics.md +299 -0
  398. package/skills/engineering/architecture/refs/examples-saas-trading.md +291 -0
  399. package/skills/engineering/architecture/refs/patterns-advanced.md +238 -0
  400. package/skills/engineering/architecture/refs/patterns-structural.md +303 -0
  401. package/skills/engineering/backend/SKILL.md +102 -0
  402. package/skills/engineering/backend/refs/checklists.md +146 -0
  403. package/skills/engineering/backend/refs/patterns.md +181 -0
  404. package/skills/engineering/debugging/SKILL.md +99 -0
  405. package/skills/engineering/debugging/refs/patterns.md +248 -0
  406. package/skills/engineering/debugging/refs/process.md +203 -0
  407. package/skills/engineering/docs/SKILL.md +97 -0
  408. package/skills/engineering/engineering/SKILL.md +88 -0
  409. package/skills/engineering/engineering/refs/checklists.md +91 -0
  410. package/skills/engineering/engineering/refs/templates.md +71 -0
  411. package/skills/engineering/frontend/SKILL.md +92 -0
  412. package/skills/engineering/frontend/refs/checklists.md +96 -0
  413. package/skills/engineering/frontend/refs/patterns.md +167 -0
  414. package/skills/engineering/integration/SKILL.md +183 -0
  415. package/skills/engineering/integration/refs/error-handling-best-practices.md +139 -0
  416. package/skills/engineering/integration/refs/error-handling-error-classes-typescript.md +212 -0
  417. package/skills/engineering/integration/refs/error-handling-error-response-format.md +301 -0
  418. package/skills/engineering/integration/refs/error-handling-retry-strategies.md +190 -0
  419. package/skills/engineering/integration/refs/event-schemas-best-practices.md +225 -0
  420. package/skills/engineering/integration/refs/event-schemas-event-naming-conventions.md +303 -0
  421. package/skills/engineering/integration/refs/event-schemas-event-structure.md +288 -0
  422. package/skills/engineering/integration/refs/graphql-best-practices.md +138 -0
  423. package/skills/engineering/integration/refs/graphql-error-handling.md +198 -0
  424. package/skills/engineering/integration/refs/graphql-graphql-basics.md +197 -0
  425. package/skills/engineering/integration/refs/graphql-query-examples.md +226 -0
  426. package/skills/engineering/integration/refs/graphql-schema-design-patterns.md +280 -0
  427. package/skills/engineering/integration/refs/grpc-grpc-overview.md +246 -0
  428. package/skills/engineering/integration/refs/grpc-implementation-examples.md +269 -0
  429. package/skills/engineering/integration/refs/grpc-metadata-headers.md +304 -0
  430. package/skills/engineering/integration/refs/grpc-testing.md +49 -0
  431. package/skills/engineering/integration/refs/openapi-template.yaml +682 -0
  432. package/skills/engineering/integration/refs/resilience-best-practices.md +109 -0
  433. package/skills/engineering/integration/refs/resilience-circuit-breaker-pattern.md +302 -0
  434. package/skills/engineering/integration/refs/resilience-rate-limiting.md +245 -0
  435. package/skills/engineering/integration/refs/resilience-timeout-pattern.md +212 -0
  436. package/skills/engineering/integration/refs/rest-api-fundamentals.md +299 -0
  437. package/skills/engineering/integration/refs/rest-api-responses-security.md +302 -0
  438. package/skills/engineering/integration/refs/versioning-breaking-changes.md +237 -0
  439. package/skills/engineering/integration/refs/versioning-migration-strategies.md +257 -0
  440. package/skills/engineering/integration/refs/versioning-versioning-strategies.md +296 -0
  441. package/skills/engineering/large-scale-migration/SKILL.md +65 -0
  442. package/skills/engineering/patch/SKILL.md +184 -0
  443. package/skills/engineering/refs/arch.md +126 -0
  444. package/skills/engineering/refs/debug.md +142 -0
  445. package/skills/engineering/refs/docs.md +190 -0
  446. package/skills/engineering/refs/plan.md +109 -0
  447. package/skills/engineering/refs/review.md +138 -0
  448. package/skills/engineering/system-design/SKILL.md +154 -0
  449. package/skills/engineering/system-design/refs/anti-patterns-big-ball-of-mud.md +254 -0
  450. package/skills/engineering/system-design/refs/anti-patterns-circular-dependencies.md +241 -0
  451. package/skills/engineering/system-design/refs/anti-patterns-feature-envy.md +168 -0
  452. package/skills/engineering/system-design/refs/anti-patterns-god-object.md +247 -0
  453. package/skills/engineering/system-design/refs/component-template-lifecycle.md +210 -0
  454. package/skills/engineering/system-design/refs/component-template-maintenance.md +219 -0
  455. package/skills/engineering/system-design/refs/component-template-structure.md +276 -0
  456. package/skills/engineering/system-design/refs/dependencies-best-practices.md +260 -0
  457. package/skills/engineering/system-design/refs/dependencies-dependency-principles.md +295 -0
  458. package/skills/engineering/system-design/refs/dependencies-dependency-tracking.md +261 -0
  459. package/skills/engineering/system-design/refs/interface-template-lifecycle.md +211 -0
  460. package/skills/engineering/system-design/refs/interface-template-maintenance.md +212 -0
  461. package/skills/engineering/system-design/refs/interface-template-structure.md +269 -0
  462. package/skills/engineering/system-design/refs/patterns-dependency-injection.md +151 -0
  463. package/skills/engineering/system-design/refs/patterns-facade-pattern.md +257 -0
  464. package/skills/engineering/system-design/refs/patterns-layered-pattern.md +204 -0
  465. package/skills/engineering/system-design/refs/patterns-plugin-architecture.md +229 -0
  466. package/skills/engineering/unit-test-quality/SKILL.md +194 -0
  467. package/skills/ground/SKILL.md +130 -0
  468. package/skills/integration-discovery/SKILL.md +168 -0
  469. package/skills/integration-discovery/refs/capabilities.md +282 -0
  470. package/skills/integration-discovery/refs/cli-detection.md +295 -0
  471. package/skills/integration-discovery/refs/discovery-sources.md +233 -0
  472. package/skills/integration-discovery/refs/task-patterns.md +206 -0
  473. package/skills/jam/SKILL.md +45 -0
  474. package/skills/jam/refs/facilitation-patterns.md +125 -0
  475. package/skills/jam/refs/quick.md +64 -0
  476. package/skills/jam/refs/synthesis-patterns.md +114 -0
  477. package/skills/multi-model/SKILL.md +168 -0
  478. package/skills/multi-model/refs/aichat.md +119 -0
  479. package/skills/multi-model/refs/aider.md +100 -0
  480. package/skills/multi-model/refs/auditability.md +238 -0
  481. package/skills/multi-model/refs/codex.md +169 -0
  482. package/skills/multi-model/refs/context.md +306 -0
  483. package/skills/multi-model/refs/copilot.md +161 -0
  484. package/skills/multi-model/refs/examples.md +224 -0
  485. package/skills/multi-model/refs/gemini.md +185 -0
  486. package/skills/multi-model/refs/goose.md +112 -0
  487. package/skills/multi-model/refs/llm.md +124 -0
  488. package/skills/multi-model/refs/opencode.md +196 -0
  489. package/skills/multi-model/refs/orchestration.md +188 -0
  490. package/skills/multi-model/refs/pi.md +208 -0
  491. package/skills/persona/SKILL.md +144 -0
  492. package/skills/persona/refs/define.md +133 -0
  493. package/skills/platform/actions/refs/actions.md +114 -0
  494. package/skills/platform/audit/SKILL.md +174 -0
  495. package/skills/platform/audit/refs/audit.md +145 -0
  496. package/skills/platform/audit/refs/checklists-evidence-operations.md +144 -0
  497. package/skills/platform/audit/refs/checklists-gdpr-pci-evidence.md +213 -0
  498. package/skills/platform/audit/refs/checklists-soc2-hipaa.md +120 -0
  499. package/skills/platform/audit/refs/frameworks-gdpr-pci.md +225 -0
  500. package/skills/platform/audit/refs/frameworks-soc2-hipaa.md +228 -0
  501. package/skills/platform/compliance/SKILL.md +169 -0
  502. package/skills/platform/compliance/refs/checklists.md +303 -0
  503. package/skills/platform/compliance/refs/compliance.md +117 -0
  504. package/skills/platform/compliance/refs/frameworks.md +282 -0
  505. package/skills/platform/errors/SKILL.md +183 -0
  506. package/skills/platform/errors/refs/patterns.md +271 -0
  507. package/skills/platform/errors/refs/severity.md +264 -0
  508. package/skills/platform/gate-benchmark-rebaseline/SKILL.md +108 -0
  509. package/skills/platform/gh/refs/gh.md +105 -0
  510. package/skills/platform/gh-cli/SKILL.md +120 -0
  511. package/skills/platform/gh-cli/refs/automation.md +63 -0
  512. package/skills/platform/gh-cli/refs/gh-ops.md +103 -0
  513. package/skills/platform/gh-cli/refs/patterns.md +132 -0
  514. package/skills/platform/gh-cli/scripts/gh_ops.py +454 -0
  515. package/skills/platform/github-actions/SKILL.md +159 -0
  516. package/skills/platform/github-actions/refs/security.md +150 -0
  517. package/skills/platform/github-actions/refs/templates.md +230 -0
  518. package/skills/platform/github-actions/refs/troubleshooting.md +174 -0
  519. package/skills/platform/github-actions/scripts/workflow_gen.py +215 -0
  520. package/skills/platform/gitlab-ci/SKILL.md +140 -0
  521. package/skills/platform/gitlab-ci/refs/templates.md +223 -0
  522. package/skills/platform/gitlab-ci/refs/troubleshooting.md +213 -0
  523. package/skills/platform/glab-cli/SKILL.md +133 -0
  524. package/skills/platform/glab-cli/refs/ci-debugging.md +95 -0
  525. package/skills/platform/glab-cli/refs/glab-ops.md +78 -0
  526. package/skills/platform/glab-cli/refs/patterns.md +131 -0
  527. package/skills/platform/glab-cli/scripts/glab_ops.py +313 -0
  528. package/skills/platform/health/SKILL.md +177 -0
  529. package/skills/platform/health/refs/health.md +72 -0
  530. package/skills/platform/health/refs/sources.md +302 -0
  531. package/skills/platform/incident/refs/incident.md +136 -0
  532. package/skills/platform/infra/refs/infra.md +104 -0
  533. package/skills/platform/observability/SKILL.md +128 -0
  534. package/skills/platform/observability/refs/toolchain-discovery.md +243 -0
  535. package/skills/platform/prereq-doctor/SKILL.md +57 -0
  536. package/skills/platform/prereq-doctor/refs/tool-registry.md +58 -0
  537. package/skills/platform/traces/refs/traces.md +101 -0
  538. package/skills/product/acceptance-criteria/SKILL.md +193 -0
  539. package/skills/product/acceptance-criteria/refs/ac-anti-patterns.md +291 -0
  540. package/skills/product/acceptance-criteria/refs/ac-examples.md +277 -0
  541. package/skills/product/accessibility/SKILL.md +197 -0
  542. package/skills/product/accessibility/refs/aria-patterns-basics.md +250 -0
  543. package/skills/product/accessibility/refs/aria-patterns-dynamic.md +187 -0
  544. package/skills/product/accessibility/refs/aria-patterns-interactive.md +246 -0
  545. package/skills/product/accessibility/refs/audit-report-findings.md +248 -0
  546. package/skills/product/accessibility/refs/audit-report-results.md +276 -0
  547. package/skills/product/accessibility/refs/common-violations-html-css.md +270 -0
  548. package/skills/product/accessibility/refs/common-violations-interactive.md +303 -0
  549. package/skills/product/accessibility/refs/keyboard-testing-basics.md +222 -0
  550. package/skills/product/accessibility/refs/keyboard-testing-patterns.md +173 -0
  551. package/skills/product/accessibility/refs/screen-reader-testing-advanced.md +294 -0
  552. package/skills/product/accessibility/refs/screen-reader-testing-commands.md +255 -0
  553. package/skills/product/accessibility/refs/wcag-checklist.md +262 -0
  554. package/skills/product/analyze/SKILL.md +164 -0
  555. package/skills/product/analyze/refs/algorithms.md +238 -0
  556. package/skills/product/analyze/refs/sentiment-patterns.md +180 -0
  557. package/skills/product/imagery/SKILL.md +97 -0
  558. package/skills/product/imagery/alter/SKILL.md +105 -0
  559. package/skills/product/imagery/alter/refs/editing-reference.md +146 -0
  560. package/skills/product/imagery/create/SKILL.md +109 -0
  561. package/skills/product/imagery/create/refs/prompt-engineering.md +112 -0
  562. package/skills/product/imagery/create/refs/provider-reference.md +219 -0
  563. package/skills/product/imagery/review/SKILL.md +101 -0
  564. package/skills/product/imagery/review/refs/analysis-lenses.md +136 -0
  565. package/skills/product/imagery/review/refs/quality-gates.md +153 -0
  566. package/skills/product/imagery/scripts/analyze.sh +23 -0
  567. package/skills/product/imagery/scripts/edit.sh +14 -0
  568. package/skills/product/imagery/scripts/generate.sh +13 -0
  569. package/skills/product/imagery/scripts/provider.py +787 -0
  570. package/skills/product/listen/SKILL.md +175 -0
  571. package/skills/product/listen/refs/channels.md +220 -0
  572. package/skills/product/mockup/SKILL.md +106 -0
  573. package/skills/product/mockup/refs/templates.md +95 -0
  574. package/skills/product/refs/a11y.md +109 -0
  575. package/skills/product/refs/acceptance.md +79 -0
  576. package/skills/product/refs/align.md +67 -0
  577. package/skills/product/refs/analyze.md +77 -0
  578. package/skills/product/refs/elicit.md +67 -0
  579. package/skills/product/refs/listen.md +58 -0
  580. package/skills/product/refs/mockup.md +77 -0
  581. package/skills/product/refs/screenshot.md +59 -0
  582. package/skills/product/refs/strategy.md +77 -0
  583. package/skills/product/refs/synthesize.md +54 -0
  584. package/skills/product/refs/ux-review.md +68 -0
  585. package/skills/product/refs/ux.md +101 -0
  586. package/skills/product/requirements-analysis/SKILL.md +136 -0
  587. package/skills/product/requirements-analysis/refs/requirements-example-auth.md +264 -0
  588. package/skills/product/requirements-analysis/refs/requirements-example-export-integration.md +88 -0
  589. package/skills/product/requirements-analysis/refs/requirements-output-format-template.md +247 -0
  590. package/skills/product/requirements-analysis/refs/user-story-guide.md +296 -0
  591. package/skills/product/requirements-graph/SKILL.md +155 -0
  592. package/skills/product/requirements-graph/refs/examples.md +223 -0
  593. package/skills/product/requirements-graph/refs/schema.md +162 -0
  594. package/skills/product/requirements-migrate/SKILL.md +90 -0
  595. package/skills/product/requirements-navigate/SKILL.md +141 -0
  596. package/skills/product/requirements-navigate/refs/meta-templates.md +141 -0
  597. package/skills/product/screenshot/SKILL.md +147 -0
  598. package/skills/product/strategy/SKILL.md +198 -0
  599. package/skills/product/strategy/refs/frameworks.md +295 -0
  600. package/skills/product/strategy/refs/templates-competitive-market.md +299 -0
  601. package/skills/product/strategy/refs/templates-roi-value.md +207 -0
  602. package/skills/product/synthesize/SKILL.md +116 -0
  603. package/skills/product/synthesize/refs/journey-mapping.md +212 -0
  604. package/skills/product/synthesize/refs/prioritization.md +193 -0
  605. package/skills/product/ux-review/SKILL.md +164 -0
  606. package/skills/product/visual-direction/SKILL.md +137 -0
  607. package/skills/product/visual-review/SKILL.md +131 -0
  608. package/skills/runtime-exec/SKILL.md +138 -0
  609. package/skills/search/codebase-narrator/SKILL.md +131 -0
  610. package/skills/search/codebase-narrator/refs/output-template.md +100 -0
  611. package/skills/smaht/SKILL.md +72 -0
  612. package/skills/smaht/discovery/SKILL.md +65 -0
  613. package/skills/smaht/intent/SKILL.md +89 -0
  614. package/skills/smaht/propose-skills/SKILL.md +142 -0
  615. package/skills/smaht/refs/state.md +76 -0
  616. package/skills/swarm/SKILL.md +132 -0
  617. package/skills/swarm/refs/fan-out.md +104 -0
  618. package/skills/swarm/refs/independent-verification.md +86 -0
  619. package/skills/swarm/refs/receipts-and-evidence.md +69 -0
  620. package/skills/swarm/refs/recon-synthesis.md +87 -0
  621. package/skills/swarm/refs/ship-discipline.md +90 -0
  622. package/skills/wickedizer/SKILL.md +147 -0
  623. package/skills/wickedizer/refs/artifact-types.md +238 -0
  624. package/skills/wickedizer/refs/complexity.md +278 -0
  625. package/skills/wickedizer/refs/de-ai-pass.md +140 -0
  626. package/skills/wickedizer/refs/failure-modes.md +249 -0
  627. package/skills/wickedizer/refs/patterns.md +282 -0
  628. package/skills/wickedizer/refs/review.md +221 -0
  629. package/skills/wickedizer/refs/structure.md +282 -0
  630. package/skills/wickedizer/refs/voice-profile.md +125 -0
  631. package/skills/workflow/SKILL.md +132 -0
  632. package/skills/workflow/refs/archetype-adjustments.md +205 -0
  633. package/skills/workflow/refs/evidence.md +58 -0
  634. package/skills/workflow/refs/integration.md +130 -0
  635. package/skills/workflow/refs/risk-dimension-signals.md +260 -0
  636. package/skills/workflow/refs/scoring-rubric.md +49 -0
  637. package/skills/workflow/refs/signal-keywords.md +176 -0
  638. package/skills/workflow/refs/specialist-routing-rules.md +159 -0
  639. package/skills/worktrees/SKILL.md +87 -0
  640. package/skills/worktrees/refs/recipes.md +96 -0
@@ -0,0 +1,357 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ _agents.py — Dynamic agent loader.
4
+
5
+ Loads agent definitions from disk:
6
+ - Disk agents: agents/{domain}/*.md files shipped with the plugin.
7
+ Always available.
8
+
9
+ Usage:
10
+ from _agents import AgentLoader
11
+
12
+ loader = AgentLoader(agents_dir=Path("agents/"))
13
+ loader.load_disk_agents(agents_dir)
14
+ profile = loader.get("senior-engineer")
15
+ """
16
+
17
+ import json
18
+ import sys
19
+ from dataclasses import dataclass, field
20
+ from pathlib import Path
21
+ from typing import Any
22
+
23
+ # ---------------------------------------------------------------------------
24
+ # AgentProfile dataclass
25
+ # ---------------------------------------------------------------------------
26
+
27
+
28
+ @dataclass
29
+ class AgentProfile:
30
+ """Normalized agent definition — common format for disk and CP sources.
31
+
32
+ Fields:
33
+ name: Unique agent identifier (kebab-case).
34
+ domain: Domain namespace (e.g. "engineering", "platform").
35
+ system_prompt: Full system prompt text.
36
+ capabilities: List of capability strings (e.g. ["code-review"]).
37
+ traits: List of trait strings (e.g. ["pragmatic", "concise"]).
38
+ metadata: Arbitrary key/value pairs; includes "source" and others.
39
+ """
40
+
41
+ name: str
42
+ domain: str = ""
43
+ system_prompt: str = ""
44
+ capabilities: list[str] = field(default_factory=list)
45
+ traits: list[str] = field(default_factory=list)
46
+ metadata: dict[str, Any] = field(default_factory=dict)
47
+
48
+ def to_dict(self) -> dict:
49
+ return {
50
+ "name": self.name,
51
+ "domain": self.domain,
52
+ "system_prompt": self.system_prompt,
53
+ "capabilities": self.capabilities,
54
+ "traits": self.traits,
55
+ "metadata": self.metadata,
56
+ }
57
+
58
+
59
+ # ---------------------------------------------------------------------------
60
+ # AgentLoader
61
+ # ---------------------------------------------------------------------------
62
+
63
+
64
+ class AgentLoader:
65
+ """Load and retrieve agent profiles from disk.
66
+
67
+ Lifecycle (called once in bootstrap.py):
68
+ loader = AgentLoader()
69
+ loader.load_disk_agents(agents_dir)
70
+ profile = loader.get("senior-engineer")
71
+ """
72
+
73
+ def __init__(self) -> None:
74
+ self._agents: dict[str, AgentProfile] = {}
75
+
76
+ # ------------------------------------------------------------------
77
+ # Loading
78
+ # ------------------------------------------------------------------
79
+
80
+ def load_disk_agents(self, agents_dir: Path) -> dict[str, AgentProfile]:
81
+ """Scan agents_dir recursively for *.md agent files and load them.
82
+
83
+ Each markdown file must have YAML frontmatter with at least a `name`
84
+ field. Additional recognized frontmatter keys: domain, description,
85
+ capabilities (list), traits (list), model, color.
86
+
87
+ The body of the markdown file (after frontmatter) becomes system_prompt.
88
+
89
+ Args:
90
+ agents_dir: Path to the agents/ directory (may contain subdirs).
91
+
92
+ Returns:
93
+ Dict mapping agent name -> AgentProfile. Also stored internally.
94
+ """
95
+ if not agents_dir.exists():
96
+ return {}
97
+
98
+ for md_file in sorted(agents_dir.rglob("*.md")):
99
+ profile = _parse_agent_md(md_file)
100
+ if profile is None:
101
+ continue
102
+ self._agents[profile.name] = profile
103
+
104
+ return dict(self._agents)
105
+
106
+ # ------------------------------------------------------------------
107
+ # Retrieval
108
+ # ------------------------------------------------------------------
109
+
110
+ def get(self, name: str) -> AgentProfile | None:
111
+ """Look up an agent by name.
112
+
113
+ Args:
114
+ name: Agent name (kebab-case, e.g. "senior-engineer").
115
+
116
+ Returns:
117
+ AgentProfile, or None if no agent with that name is loaded.
118
+ """
119
+ return self._agents.get(name)
120
+
121
+ def all(self) -> dict[str, AgentProfile]:
122
+ """Return a shallow copy of all loaded agents."""
123
+ return dict(self._agents)
124
+
125
+ def count(self) -> int:
126
+ return len(self._agents)
127
+
128
+ def serialize(self) -> list[dict]:
129
+ """Serialize all agents to a JSON-safe list (for session state file)."""
130
+ return [p.to_dict() for p in self._agents.values()]
131
+
132
+ @classmethod
133
+ def deserialize(cls, data: list[dict]) -> "AgentLoader":
134
+ """Reconstruct an AgentLoader from a previously serialized list."""
135
+ loader = cls()
136
+ for rec in data:
137
+ name = rec.get("name")
138
+ if not name:
139
+ continue
140
+ loader._agents[name] = AgentProfile(
141
+ name=name,
142
+ domain=rec.get("domain", ""),
143
+ system_prompt=rec.get("system_prompt", ""),
144
+ capabilities=rec.get("capabilities") or [],
145
+ traits=rec.get("traits") or [],
146
+ metadata=rec.get("metadata") or {},
147
+ )
148
+ return loader
149
+
150
+
151
+ # ---------------------------------------------------------------------------
152
+ # Markdown frontmatter parser (stdlib-only, no PyYAML)
153
+ # ---------------------------------------------------------------------------
154
+
155
+ _FRONTMATTER_START = "---"
156
+ _FRONTMATTER_END = "---"
157
+
158
+
159
+ def _parse_agent_md(path: Path) -> AgentProfile | None:
160
+ """Parse a Claude Code agent markdown file into an AgentProfile.
161
+
162
+ Format:
163
+ ---
164
+ name: agent-name
165
+ description: |
166
+ Optional description
167
+ domain: engineering # optional
168
+ capabilities: # optional list
169
+ - code-review
170
+ traits: # optional list
171
+ - pragmatic
172
+ model: sonnet # stored in metadata
173
+ color: blue # stored in metadata
174
+ ---
175
+
176
+ # Agent Title
177
+
178
+ System prompt body...
179
+
180
+ Returns:
181
+ AgentProfile, or None if the file lacks a valid name field.
182
+ """
183
+ try:
184
+ raw = path.read_text(encoding="utf-8")
185
+ except OSError:
186
+ return None
187
+
188
+ frontmatter, body = _split_frontmatter(raw)
189
+ if frontmatter is None:
190
+ # No frontmatter — use filename as name, whole file as system_prompt
191
+ name = path.stem
192
+ domain = _infer_domain(path)
193
+ return AgentProfile(
194
+ name=name,
195
+ domain=domain,
196
+ system_prompt=raw.strip(),
197
+ metadata={"source": "disk", "file": str(path)},
198
+ )
199
+
200
+ parsed = _parse_simple_yaml(frontmatter)
201
+ name = parsed.get("name") or path.stem
202
+ if not name:
203
+ return None
204
+
205
+ domain = parsed.get("domain") or _infer_domain(path)
206
+
207
+ # Build metadata from remaining frontmatter keys
208
+ metadata_keys = {"model", "color", "version", "author", "allowed-tools"}
209
+ extra_meta = {k: v for k, v in parsed.items() if k in metadata_keys}
210
+ extra_meta["source"] = "disk"
211
+ extra_meta["file"] = str(path)
212
+
213
+ # Extract tool-capabilities for capability-based dynamic tool routing
214
+ tool_caps = _to_list(parsed.get("tool-capabilities"))
215
+ if tool_caps:
216
+ extra_meta["tool_capabilities"] = tool_caps
217
+
218
+ # Parse allowed-tools into a list for the resolver
219
+ allowed_tools_list = _to_list(parsed.get("allowed-tools"))
220
+ if allowed_tools_list:
221
+ extra_meta["allowed_tools_list"] = allowed_tools_list
222
+
223
+ return AgentProfile(
224
+ name=name,
225
+ domain=domain,
226
+ system_prompt=body.strip(),
227
+ capabilities=_to_list(parsed.get("capabilities")),
228
+ traits=_to_list(parsed.get("traits")),
229
+ metadata=extra_meta,
230
+ )
231
+
232
+
233
+ def _split_frontmatter(raw: str) -> tuple[str | None, str]:
234
+ """Split raw markdown into (frontmatter, body).
235
+
236
+ Returns (None, raw) if no YAML frontmatter block is found.
237
+ """
238
+ lines = raw.split("\n")
239
+ if not lines or lines[0].strip() != _FRONTMATTER_START:
240
+ return None, raw
241
+
242
+ end_idx = None
243
+ for i, line in enumerate(lines[1:], start=1):
244
+ if line.strip() == _FRONTMATTER_END:
245
+ end_idx = i
246
+ break
247
+
248
+ if end_idx is None:
249
+ return None, raw
250
+
251
+ frontmatter = "\n".join(lines[1:end_idx])
252
+ body = "\n".join(lines[end_idx + 1 :])
253
+ return frontmatter, body
254
+
255
+
256
+ def _parse_simple_yaml(text: str) -> dict[str, Any]:
257
+ """Minimal YAML parser for Claude Code agent frontmatter.
258
+
259
+ Handles the subset of YAML used in agent files:
260
+ - key: scalar_value
261
+ - key: |
262
+ multi-line block (dedented)
263
+ - key:
264
+ - list_item_1
265
+ - list_item_2
266
+
267
+ Does NOT handle nested dicts, anchors, or other YAML features.
268
+ """
269
+ result: dict[str, Any] = {}
270
+ lines = text.split("\n")
271
+ i = 0
272
+
273
+ while i < len(lines):
274
+ line = lines[i]
275
+
276
+ # Skip blank lines and comments
277
+ if not line.strip() or line.strip().startswith("#"):
278
+ i += 1
279
+ continue
280
+
281
+ # Key: value or Key:
282
+ if ":" not in line:
283
+ i += 1
284
+ continue
285
+
286
+ key_part, _, value_part = line.partition(":")
287
+ key = key_part.strip()
288
+ value = value_part.strip()
289
+
290
+ if not key:
291
+ i += 1
292
+ continue
293
+
294
+ # Block scalar (|)
295
+ if value == "|":
296
+ block_lines: list[str] = []
297
+ i += 1
298
+ while i < len(lines):
299
+ bl = lines[i]
300
+ # Block ends when we hit a line at root indentation (no leading space)
301
+ if bl and not bl.startswith(" ") and not bl.startswith("\t"):
302
+ break
303
+ block_lines.append(bl)
304
+ i += 1
305
+ result[key] = "\n".join(line.rstrip() for line in block_lines).strip()
306
+ continue
307
+
308
+ # Inline list (next lines starting with " -")
309
+ if value == "":
310
+ list_items: list[str] = []
311
+ j = i + 1
312
+ while j < len(lines):
313
+ candidate = lines[j].strip()
314
+ if candidate.startswith("- "):
315
+ list_items.append(candidate[2:].strip())
316
+ j += 1
317
+ elif candidate == "-":
318
+ list_items.append("")
319
+ j += 1
320
+ else:
321
+ break
322
+ if list_items:
323
+ result[key] = list_items
324
+ i = j
325
+ continue
326
+
327
+ # Plain scalar — strip surrounding quotes
328
+ if value.startswith(('"', "'")):
329
+ value = value[1:-1] if len(value) > 1 and value[-1] == value[0] else value
330
+ result[key] = value
331
+ i += 1
332
+
333
+ return result
334
+
335
+
336
+ def _infer_domain(path: Path) -> str:
337
+ """Infer domain from path: agents/{domain}/agent.md -> domain."""
338
+ parts = path.parts
339
+ # Look for the 'agents' segment and take the next part as domain
340
+ for idx, part in enumerate(parts):
341
+ if part == "agents" and idx + 2 < len(parts):
342
+ return parts[idx + 1]
343
+ return ""
344
+
345
+
346
+ def _to_list(value: Any) -> list[str]:
347
+ """Normalize a YAML value to a list of strings."""
348
+ if value is None:
349
+ return []
350
+ if isinstance(value, list):
351
+ return [str(v) for v in value]
352
+ if isinstance(value, str):
353
+ # Comma-separated or single value
354
+ if "," in value:
355
+ return [v.strip() for v in value.split(",") if v.strip()]
356
+ return [value.strip()] if value.strip() else []
357
+ return []
@@ -0,0 +1,2 @@
1
+ # _brain_ingest — internal infrastructure for brain ingestion.
2
+ # Feeds session facts and other internal events into wicked-brain.
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Session-fact extractor over native Claude tasks.
4
+
5
+ Replaces the smaht/v2 FactExtractor + HistoryCondenser turn-log pipeline
6
+ that was deleted in Gate 4 Phase 2 of the v6 rebuild (#428). Reads native
7
+ tasks written by TaskCreate/TaskUpdate to
8
+ ${CLAUDE_CONFIG_DIR:-~/.claude}/tasks/{session_id}/*.json and extracts
9
+ session-level facts using the same heuristic patterns as the old
10
+ FactExtractor.
11
+
12
+ Source of truth shift:
13
+ - v5: wicked-smaht session directory turn log (user/assistant messages)
14
+ - v6: native task records (subject + description, filtered to completed)
15
+
16
+ The emission shape on wicked-bus stays the same — `wicked.fact.extracted`
17
+ events with {type, content, entities, source, session_id} — so the brain
18
+ auto-memorize subscriber is unaffected.
19
+
20
+ Fact types (mirrors brain auto-memorize policy):
21
+ - decision — "decided on X", "chose Y", "let's use Z"
22
+ - discovery — "found that X", "turns out Y"
23
+ - artifact — "created X", "wrote Y"
24
+ - problem_solved — "fixed X", "resolved Y"
25
+ - context — "the system uses X", "currently running Y"
26
+
27
+ Only `decision` and `discovery` are emittable (brain re-filters).
28
+
29
+ stdlib-only. Fails open — returns [] on any I/O or parse error.
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ import json
35
+ import os
36
+ import re
37
+ import sys
38
+ import uuid
39
+ from dataclasses import dataclass, field, asdict
40
+ from datetime import datetime, timezone
41
+ from pathlib import Path
42
+ from typing import Iterable, Optional
43
+
44
+
45
+ FACT_TYPES = ("decision", "discovery", "artifact", "problem_solved", "context")
46
+ EMITTABLE_FACT_TYPES = frozenset({"decision", "discovery"})
47
+
48
+
49
+ @dataclass
50
+ class SessionFact:
51
+ """A structured fact extracted from a native task record."""
52
+
53
+ id: str
54
+ type: str
55
+ content: str
56
+ entities: list = field(default_factory=list)
57
+ source: str = "task" # always "task" in v6 — native task origin
58
+ timestamp: str = ""
59
+ task_id: str = ""
60
+
61
+ def __post_init__(self) -> None:
62
+ if not self.id:
63
+ self.id = str(uuid.uuid4())[:8]
64
+ if not self.timestamp:
65
+ self.timestamp = datetime.now(timezone.utc).isoformat()
66
+
67
+ def to_dict(self) -> dict:
68
+ return asdict(self)
69
+
70
+
71
+ # --- Extraction patterns (ported verbatim from smaht/v2/fact_extractor.py) ---
72
+
73
+ _DECISION_PATTERNS = [
74
+ (r"let's (?:go with|use|do) ([^.!?\n]{10,100})", "decision"),
75
+ (r"decided (?:on|to) ([^.!?\n]{10,100})", "decision"),
76
+ (r"chose ([^.!?\n]{10,100})", "decision"),
77
+ (r"we(?:'ll| will) use ([^.!?\n]{10,100})", "decision"),
78
+ (r"going (?:to|with) ([^.!?\n]{10,100})", "decision"),
79
+ (r"switched to ([^.!?\n]{10,100})", "decision"),
80
+ ]
81
+
82
+ _DISCOVERY_PATTERNS = [
83
+ (r"(?:found|discovered) (?:that |out )([^.!?\n]{10,100})", "discovery"),
84
+ (r"turns out ([^.!?\n]{10,100})", "discovery"),
85
+ (r"(?:realized|noticed) (?:that )?([^.!?\n]{10,100})", "discovery"),
86
+ (r"the (?:issue|problem|root cause) (?:is|was) ([^.!?\n]{10,100})", "discovery"),
87
+ ]
88
+
89
+ _ARTIFACT_PATTERNS = [
90
+ (r"(?:created|wrote|generated|built) ([^.!?\n]{5,80})", "artifact"),
91
+ (r"(?:added|implemented) ([^.!?\n]{5,80})", "artifact"),
92
+ ]
93
+
94
+ _PROBLEM_SOLVED_PATTERNS = [
95
+ (r"(?:fixed|resolved|solved) ([^.!?\n]{10,100})", "problem_solved"),
96
+ (r"(?:the fix|solution) (?:is|was) ([^.!?\n]{10,100})", "problem_solved"),
97
+ ]
98
+
99
+ _CONTEXT_PATTERNS = [
100
+ (r"the system (?:uses|has|runs) ([^.!?\n]{10,80})", "context"),
101
+ (r"currently (?:using|running|on) ([^.!?\n]{10,80})", "context"),
102
+ (r"our (?:stack|setup|architecture) (?:is|includes) ([^.!?\n]{10,80})", "context"),
103
+ ]
104
+
105
+ _ALL_PATTERNS = (
106
+ _DECISION_PATTERNS
107
+ + _DISCOVERY_PATTERNS
108
+ + _ARTIFACT_PATTERNS
109
+ + _PROBLEM_SOLVED_PATTERNS
110
+ + _CONTEXT_PATTERNS
111
+ )
112
+
113
+
114
+ _TECH_NAMES = (
115
+ "Redis", "Postgres", "PostgreSQL", "MySQL", "MongoDB", "SQLite",
116
+ "Docker", "Kubernetes", "AWS", "GCP", "Azure",
117
+ "React", "Vue", "Angular", "FastAPI", "Django", "Flask", "Express",
118
+ "JWT", "OAuth", "GraphQL", "REST", "gRPC",
119
+ "Stripe", "Kafka", "RabbitMQ", "Elasticsearch",
120
+ )
121
+
122
+ _FILE_PATH_RE = re.compile(
123
+ r"([a-zA-Z_][a-zA-Z0-9_/.-]*\."
124
+ r"(?:py|ts|js|tsx|jsx|json|yaml|yml|md|sql|java|go|rs|sh))\b"
125
+ )
126
+
127
+
128
+ def _extract_entities(text: str) -> list:
129
+ """Extract entity references (files, technologies, services) from text."""
130
+ entities: list = []
131
+
132
+ files = _FILE_PATH_RE.findall(text)
133
+ entities.extend(files[:5])
134
+
135
+ for tech in _TECH_NAMES:
136
+ if re.search(rf"\b{re.escape(tech)}\b", text, re.IGNORECASE) and tech not in entities:
137
+ entities.append(tech)
138
+
139
+ return entities[:8]
140
+
141
+
142
+ def _tasks_dir(session_id: str) -> Path:
143
+ """Resolve the native tasks directory for a session.
144
+
145
+ Honors CLAUDE_CONFIG_DIR; defaults to ~/.claude.
146
+ """
147
+ base = os.environ.get("CLAUDE_CONFIG_DIR")
148
+ if base:
149
+ root = Path(base).expanduser()
150
+ else:
151
+ root = Path.home() / ".claude"
152
+ # Sanitize session_id the same way hooks/scripts/stop.py does.
153
+ safe = session_id.replace("/", "_").replace("\\", "_").replace("..", "_")
154
+ return root / "tasks" / safe
155
+
156
+
157
+ def _iter_task_records_direct(session_id: str) -> Iterable[dict]:
158
+ """Yield completed task records via direct file read (pre-PR-2 behaviour)."""
159
+ tdir = _tasks_dir(session_id)
160
+ if not tdir.exists() or not tdir.is_dir():
161
+ return
162
+
163
+ # Native task filenames are the numeric task id + .json. Sort numerically
164
+ # so earlier tasks produce earlier facts (stable order for dedup).
165
+ def _sort_key(p: Path) -> tuple:
166
+ stem = p.stem
167
+ try:
168
+ return (0, int(stem))
169
+ except ValueError:
170
+ return (1, stem)
171
+
172
+ for path in sorted(tdir.glob("*.json"), key=_sort_key):
173
+ try:
174
+ data = json.loads(path.read_text(encoding="utf-8"))
175
+ except (OSError, ValueError, json.JSONDecodeError):
176
+ continue
177
+ if not isinstance(data, dict):
178
+ continue
179
+ if data.get("status") != "completed":
180
+ continue
181
+ yield data
182
+
183
+
184
+ def _iter_task_records(session_id: str) -> Iterable[dict]:
185
+ """Yield native task JSON records for the session, oldest-first by numeric id.
186
+
187
+ Only yields tasks whose status == 'completed'.
188
+
189
+ Routing: WG_DAEMON_ENABLED=false → direct file read (unchanged);
190
+ WG_DAEMON_ENABLED=true → daemon HTTP with fallback (#596 v8-PR-2).
191
+ """
192
+ try:
193
+ # _SCRIPTS_ROOT is the parent of this file's directory.
194
+ _scripts = str(Path(__file__).resolve().parents[1])
195
+ if _scripts not in sys.path:
196
+ sys.path.insert(0, _scripts)
197
+ from crew._task_reader import read_session_tasks # type: ignore[import]
198
+ tasks = read_session_tasks(session_id, limit=500)
199
+ for t in tasks:
200
+ if isinstance(t, dict) and t.get("status") == "completed":
201
+ yield t
202
+ return
203
+ except Exception:
204
+ pass # fail open — _task_reader unavailable; fall through to direct file read
205
+ # Fallback to direct file read if import fails.
206
+ yield from _iter_task_records_direct(session_id)
207
+
208
+
209
+ def _extract_from_text(text: str, task_id: str) -> list:
210
+ """Extract facts from a text block (task subject + description)."""
211
+ if not text:
212
+ return []
213
+
214
+ facts: list = []
215
+ text_lower = text.lower()
216
+ entities = _extract_entities(text)
217
+
218
+ for pattern, fact_type in _ALL_PATTERNS:
219
+ matches = re.findall(pattern, text_lower)
220
+ for match in matches[:2]:
221
+ if isinstance(match, tuple):
222
+ match = " ".join(match)
223
+ match = match.strip()
224
+ if not match or len(match) < 5:
225
+ continue
226
+ facts.append(
227
+ SessionFact(
228
+ id=str(uuid.uuid4())[:8],
229
+ type=fact_type,
230
+ content=match,
231
+ entities=entities,
232
+ source="task",
233
+ task_id=task_id,
234
+ )
235
+ )
236
+ # Match the old FactExtractor cap of 5 per text block.
237
+ return facts[:5]
238
+
239
+
240
+ def extract_session_facts(session_id: str, limit: int = 10) -> list:
241
+ """Extract session-level facts from native task records.
242
+
243
+ Returns a list of SessionFact objects (up to `limit`), deduplicated by
244
+ lowercased content. Fails open — returns [] on any error.
245
+
246
+ The returned shape matches what hooks/scripts/stop.py::_run_memory_promotion
247
+ consumes: objects with `.type`, `.content`, `.entities`, `.source`.
248
+ """
249
+ if not session_id or limit <= 0:
250
+ return []
251
+
252
+ facts: list = []
253
+ seen: set = set()
254
+
255
+ try:
256
+ for record in _iter_task_records(session_id):
257
+ task_id = str(record.get("id", ""))
258
+ subject = str(record.get("subject", "") or "")
259
+ description = str(record.get("description", "") or "")
260
+ # Concatenate so patterns can match across subject+description;
261
+ # keeps entity extraction coherent within a single task.
262
+ text = f"{subject}. {description}".strip()
263
+
264
+ for fact in _extract_from_text(text, task_id):
265
+ key = fact.content.lower()
266
+ if key in seen:
267
+ continue
268
+ seen.add(key)
269
+ facts.append(fact)
270
+ if len(facts) >= limit:
271
+ return facts
272
+ except Exception as exc: # pragma: no cover - defensive fail-open
273
+ print(f"[wicked-mem] session fact extraction error: {exc}", file=sys.stderr)
274
+ return facts
275
+
276
+ return facts
277
+
278
+
279
+ def _self_test() -> int:
280
+ """Inline self-test with a synthetic task directory."""
281
+ import tempfile
282
+
283
+ tmp = Path(tempfile.mkdtemp(prefix="wg-sfe-"))
284
+ try:
285
+ session_id = "selftest"
286
+ sdir = tmp / "tasks" / session_id
287
+ sdir.mkdir(parents=True)
288
+
289
+ # Task 1: contains a decision + an artifact
290
+ (sdir / "1.json").write_text(json.dumps({
291
+ "id": "1",
292
+ "subject": "Wire facilitator",
293
+ "description": "We decided to use the rubric approach and created facilitator.md",
294
+ "status": "completed",
295
+ }))
296
+ # Task 2: pending — should be ignored
297
+ (sdir / "2.json").write_text(json.dumps({
298
+ "id": "2",
299
+ "subject": "Write docs",
300
+ "description": "Not done yet",
301
+ "status": "pending",
302
+ }))
303
+ # Task 3: a discovery
304
+ (sdir / "3.json").write_text(json.dumps({
305
+ "id": "3",
306
+ "subject": "Root cause",
307
+ "description": "The issue was a race condition in the event loop",
308
+ "status": "completed",
309
+ }))
310
+
311
+ os.environ["CLAUDE_CONFIG_DIR"] = str(tmp)
312
+ facts = extract_session_facts(session_id, limit=10)
313
+
314
+ types = [f.type for f in facts]
315
+ contents = [f.content for f in facts]
316
+
317
+ assert facts, f"expected at least one fact, got {facts}"
318
+ assert "decision" in types, f"expected a decision fact, got types={types}"
319
+ assert "discovery" in types, f"expected a discovery fact, got types={types}"
320
+ # pending task must not leak into facts
321
+ assert not any("not done" in c for c in contents), (
322
+ f"pending task leaked into facts: {contents}"
323
+ )
324
+ # Every fact must have a task_id linking it to its source
325
+ assert all(f.task_id for f in facts), (
326
+ f"facts missing task_id: {[f.to_dict() for f in facts]}"
327
+ )
328
+
329
+ emittable = [f for f in facts if f.type in EMITTABLE_FACT_TYPES]
330
+ assert emittable, "expected at least one emittable (decision/discovery) fact"
331
+
332
+ print(f"session_fact_extractor self-test: PASS ({len(facts)} facts, {len(emittable)} emittable)")
333
+ return 0
334
+ finally:
335
+ import shutil
336
+ shutil.rmtree(tmp, ignore_errors=True)
337
+ os.environ.pop("CLAUDE_CONFIG_DIR", None)
338
+
339
+
340
+ if __name__ == "__main__":
341
+ sys.exit(_self_test())