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,254 @@
1
+ """
2
+ Brain adapter for wicked-smaht context assembly.
3
+
4
+ Queries the wicked-brain FTS5 index for code and document context
5
+ relevant to the current prompt. Returns ContextItems tagged with
6
+ source="brain" so the slow path briefing formatter labels them correctly.
7
+
8
+ wicked-brain is a required dependency — context assembly is degraded without it.
9
+ When brain is unreachable, this adapter logs a warning to stderr and returns empty.
10
+ """
11
+
12
+ import json
13
+ import os
14
+ import sys
15
+ import urllib.error
16
+ import urllib.request
17
+ from pathlib import Path
18
+ from typing import List
19
+
20
+ from . import ContextItem, run_in_thread
21
+
22
+ _STOP_WORDS = frozenset({
23
+ "the", "a", "an", "is", "are", "was", "were", "be", "been", "have", "has",
24
+ "had", "do", "does", "did", "will", "would", "could", "should", "can",
25
+ "may", "might", "must", "i", "you", "we", "they", "me", "my", "your",
26
+ "this", "that", "these", "those", "what", "which", "who", "how", "why",
27
+ "when", "where", "and", "or", "but", "if", "for", "of", "to", "from",
28
+ "in", "on", "at", "by", "with", "about", "not", "so", "just", "also",
29
+ "need", "want", "let", "get", "make", "test", "check", "fix", "work",
30
+ # English filler that passes len>2 but over-constrains FTS5 AND matching
31
+ "one", "two", "all", "any", "some", "out", "use", "via", "per",
32
+ "without", "going", "through", "using", "into", "onto", "upon",
33
+ "there", "their", "then", "than", "its", "our", "has",
34
+ # Prepositions / general connectors that look content-y but aren't
35
+ "between", "across", "along", "around", "before", "after",
36
+ "exist", "exists", "show", "tell", "give", "take",
37
+ })
38
+
39
+
40
+ def _extract_keywords(prompt: str, limit: int = 3) -> str:
41
+ """Extract up to `limit` keywords for FTS5 AND query.
42
+
43
+ Position-order preserves the prompt's intent; the first non-stop words
44
+ are almost always the topic. Callers pass limit=2 for retry fallback.
45
+ """
46
+ words = prompt.lower().split()
47
+ keywords = [w for w in words if w not in _STOP_WORDS and len(w) > 2]
48
+ seen: set[str] = set()
49
+ unique = []
50
+ for w in keywords:
51
+ if w not in seen:
52
+ seen.add(w)
53
+ unique.append(w)
54
+ return " ".join(unique[:limit]) if unique else ""
55
+
56
+
57
+ def _query_brain(prompt: str) -> list:
58
+ """Query brain FTS5 index with automatic recall fallback.
59
+
60
+ FTS5 uses AND — more terms = fewer results. Try 3 terms first (higher
61
+ precision); if < 2 results, try two 2-term combinations and pick the
62
+ one with more results:
63
+ - first + third (drop middle — often the most generic term)
64
+ - first + second (standard narrowing)
65
+ """
66
+ keywords = _extract_keywords(prompt, limit=3).split()
67
+ if not keywords:
68
+ return []
69
+
70
+ query = " ".join(keywords)
71
+
72
+ try:
73
+ from _brain_port import resolve_port as _resolve_port
74
+ port = _resolve_port()
75
+
76
+ def _search(q: str) -> list:
77
+ payload = json.dumps({
78
+ "action": "search",
79
+ "params": {"query": q, "limit": 10},
80
+ }).encode("utf-8")
81
+ req = urllib.request.Request(
82
+ f"http://localhost:{port}/api",
83
+ data=payload,
84
+ headers={"Content-Type": "application/json"},
85
+ method="POST",
86
+ )
87
+ with urllib.request.urlopen(req, timeout=3) as resp:
88
+ return json.loads(resp.read().decode("utf-8")).get("results", [])
89
+
90
+ results = _search(query)
91
+ if len(results) < 2 and len(keywords) >= 3:
92
+ # Try dropping the middle keyword (often the least specific)
93
+ alt_a = f"{keywords[0]} {keywords[2]}" # first + third
94
+ alt_b = f"{keywords[0]} {keywords[1]}" # first + second
95
+ ra = _search(alt_a)
96
+ rb = _search(alt_b)
97
+ # Prefer whichever returns more results (wider recall)
98
+ results = ra if len(ra) >= len(rb) else rb
99
+ elif len(results) < 2 and len(keywords) == 2:
100
+ # Already at 2 terms; nothing further to try
101
+ pass # intentional: no-op
102
+ return results
103
+ except Exception as _e:
104
+ print(
105
+ f"smaht: brain adapter unreachable (port {port})"
106
+ f" — context assembly degraded: {type(_e).__name__}",
107
+ file=sys.stderr,
108
+ )
109
+ return []
110
+
111
+
112
+ def _keyword_score(prompt_lower: str, text: str) -> float:
113
+ """Score text by keyword overlap with prompt."""
114
+ if not text:
115
+ return 0.0
116
+ text_lower = text.lower()
117
+ score = 0.0
118
+ for word in prompt_lower.split():
119
+ if len(word) > 3 and word in text_lower:
120
+ score += 0.15
121
+ return min(score, 0.45)
122
+
123
+
124
+ def _readable_title(source_file: str) -> str:
125
+ """Convert a chunk source path to a human-readable title.
126
+
127
+ e.g. "skills-crew-workflow-refs-specialist-routing-rules.md"
128
+ → "crew / specialist-routing-rules"
129
+ """
130
+ import re as _re
131
+ # Strip leading domain prefix like "skills-", "commands-", "agents-", "hooks-"
132
+ name = _re.sub(r'^(skills|commands|agents|hooks|scenarios|scripts|docs)-', '', source_file)
133
+ # Strip .md extension
134
+ name = name.removesuffix('.md')
135
+ # Split on '-' to get components; find the domain and the tail
136
+ parts = name.split('-')
137
+ if len(parts) >= 2:
138
+ # First part is domain; rest is description
139
+ domain = parts[0]
140
+ # Skip "refs" and numeric-looking chunks
141
+ desc_parts = [p for p in parts[1:] if p != 'refs' and not p.startswith('chunk')]
142
+ if desc_parts:
143
+ return f"{domain} / {'-'.join(desc_parts)}"
144
+ return name
145
+
146
+
147
+ def _clean_snippet(raw: str) -> str:
148
+ """Strip YAML frontmatter lines and FTS highlight tags from snippet.
149
+
150
+ FTS5 snippets contain frontmatter when the brain server re-indexes full
151
+ chunk files. Strip aggressively: snake_case keys, floats, timestamps,
152
+ list tags, and separator markers.
153
+ """
154
+ import re as _re
155
+
156
+ # Remove FTS5 highlight markers and ellipsis separators
157
+ text = _re.sub(r"<[^>]+>", "", raw)
158
+ text = text.replace("…", " ").replace("...", " ")
159
+
160
+ # Patterns that indicate frontmatter / metadata noise — skip these lines
161
+ _yaml_key = _re.compile(r'^[a-z][a-z_]+:\s*') # snake_case key: value
162
+ _bare_float = _re.compile(r'^\d+\.\d+$') # e.g. "0.7"
163
+ _timestamp = _re.compile(r'^\d{4}-\d{2}-\d{2}') # ISO date
164
+ _tag_list = _re.compile(r'^- [a-z][\w\-]*$') # bare YAML tag list items
165
+ _flag_list = _re.compile(r'^- --[\w\-]+') # CLI flag list items: - --flag
166
+ _uuid_like = _re.compile(r'^[a-f0-9\-]{8,}$') # UUIDs
167
+ # Leftover path values after their YAML key was stripped
168
+ _file_path = _re.compile(r'^[\w/.\- ]+\.(md|py|js|ts|jsx|tsx|json|yaml|yml|sh|txt)$')
169
+ # chunk-ID paths: "source-name/chunk-NNN" or bare "chunk-NNN"
170
+ _chunk_id = _re.compile(r'(^|/)chunk-\d+')
171
+ # Markdown table rows: any line starting with | (data rows and separators)
172
+ _table_row = _re.compile(r'^\|')
173
+
174
+ lines = []
175
+ for line in text.split("\n"):
176
+ stripped = line.strip()
177
+ if not stripped or stripped == "---":
178
+ continue
179
+ if (_yaml_key.match(stripped)
180
+ or _bare_float.match(stripped)
181
+ or _timestamp.match(stripped)
182
+ or _tag_list.match(stripped)
183
+ or _flag_list.match(stripped)
184
+ or _uuid_like.match(stripped)
185
+ or _file_path.match(stripped)
186
+ or _chunk_id.search(stripped)
187
+ or _table_row.match(stripped)):
188
+ continue
189
+ lines.append(stripped)
190
+
191
+ result = " ".join(lines).strip()
192
+ return result[:160] if result else ""
193
+
194
+
195
+ async def query(prompt: str) -> List[ContextItem]:
196
+ """Query brain for code and document context relevant to the prompt."""
197
+ results = await run_in_thread(_query_brain, prompt)
198
+ if not results:
199
+ return []
200
+
201
+ import re
202
+ # Score against extracted keywords only (not full prompt) so incidental
203
+ # words in the prompt (e.g. "crew" in "without going through the crew
204
+ # workflow") don't boost unrelated documents that happen to mention them.
205
+ score_against = _extract_keywords(prompt, limit=3) or prompt.lower()
206
+
207
+ # First pass: build items grouped by source file (deduplicate chunks → 1 item per source)
208
+ best_by_source: dict[str, dict] = {}
209
+
210
+ for r in results:
211
+ path = r.get("path", "") or r.get("id", "")
212
+ snippet = r.get("snippet", "")
213
+
214
+ # Determine source file from chunk path
215
+ source_file = ""
216
+ if "chunks/extracted/" in path:
217
+ part = path.replace("chunks/extracted/", "").split("/chunk-")[0]
218
+ source_file = part
219
+ else:
220
+ source_file = path
221
+
222
+ clean_snippet = _clean_snippet(snippet)
223
+ kw_score = _keyword_score(score_against, f"{source_file} {clean_snippet}")
224
+ # Items with no readable snippet get a relevance floor of 0.2 so they
225
+ # rank below items that survived cleaning and only appear if budget allows.
226
+ base = 0.2 if not clean_snippet else 0.3
227
+ relevance = min(base + kw_score, 1.0)
228
+
229
+ # Keep only the highest-scoring chunk per source file
230
+ existing = best_by_source.get(source_file)
231
+ if existing is None or relevance > existing["relevance"]:
232
+ best_by_source[source_file] = {
233
+ "path": path,
234
+ "source_file": source_file,
235
+ "snippet": clean_snippet,
236
+ "relevance": relevance,
237
+ }
238
+
239
+ # Second pass: convert to ContextItems
240
+ items: List[ContextItem] = []
241
+ for source_file, entry in best_by_source.items():
242
+ title = _readable_title(source_file)
243
+ items.append(ContextItem(
244
+ id=entry["path"],
245
+ source="brain",
246
+ title=title,
247
+ summary=entry["snippet"],
248
+ excerpt=entry["snippet"][:100],
249
+ relevance=entry["relevance"],
250
+ metadata={"brain_path": entry["path"]},
251
+ ))
252
+
253
+ items.sort(key=lambda x: x.relevance, reverse=True)
254
+ return items
@@ -0,0 +1,438 @@
1
+ """
2
+ wicked-smaht adapter for Context7.
3
+
4
+ Queries external library documentation via Context7 MCP integration.
5
+ Provides graceful degradation when Context7 is unavailable.
6
+ """
7
+
8
+ import asyncio
9
+ import hashlib
10
+ import json
11
+ import sys
12
+ from datetime import datetime, timezone
13
+ from pathlib import Path
14
+ from typing import List, Optional, Dict, Any
15
+
16
+ from . import ContextItem, _SCRIPTS_ROOT
17
+
18
+ if str(_SCRIPTS_ROOT) not in sys.path:
19
+ sys.path.insert(0, str(_SCRIPTS_ROOT))
20
+
21
+ from _domain_store import get_local_path
22
+
23
+
24
+ # Cache configuration
25
+ CACHE_DIR = get_local_path("wicked-smaht", "cache", "context7")
26
+ CACHE_TTL_SECONDS = 3600 # 1 hour
27
+ MAX_CACHE_ENTRIES = 500
28
+
29
+
30
+ class Context7Cache:
31
+ """Simple file-based cache for Context7 query results."""
32
+
33
+ def __init__(self, cache_dir: Path = CACHE_DIR):
34
+ self.cache_dir = cache_dir
35
+ self.cache_dir.mkdir(parents=True, exist_ok=True)
36
+ self.index_path = cache_dir / "index.json"
37
+ self.data_dir = cache_dir / "data"
38
+ self.data_dir.mkdir(exist_ok=True)
39
+ self._load_index()
40
+
41
+ def _load_index(self):
42
+ """Load cache index from disk."""
43
+ if self.index_path.exists():
44
+ try:
45
+ with open(self.index_path) as f:
46
+ self.index = json.load(f)
47
+ except Exception:
48
+ self.index = {}
49
+ else:
50
+ self.index = {}
51
+
52
+ def _save_index(self):
53
+ """Save cache index to disk."""
54
+ with open(self.index_path, 'w') as f:
55
+ json.dump(self.index, f, indent=2)
56
+
57
+ def _cache_key(self, library_id: str, query: str) -> str:
58
+ """Generate cache key from library ID and query."""
59
+ content = f"{library_id}:{query}"
60
+ return hashlib.sha256(content.encode()).hexdigest()[:16]
61
+
62
+ def _is_valid(self, entry: Dict[str, Any]) -> bool:
63
+ """Check if cache entry is still valid."""
64
+ cached_at = datetime.fromisoformat(entry['cached_at'])
65
+ age_seconds = (datetime.now(timezone.utc) - cached_at).total_seconds()
66
+ return age_seconds < CACHE_TTL_SECONDS
67
+
68
+ def get(self, library_id: str, query: str) -> Optional[List[ContextItem]]:
69
+ """Get cached results if valid, None otherwise."""
70
+ key = self._cache_key(library_id, query)
71
+
72
+ # Check index
73
+ if key not in self.index:
74
+ return None
75
+
76
+ entry = self.index[key]
77
+
78
+ # Validate TTL
79
+ if not self._is_valid(entry):
80
+ # Clean up expired entry
81
+ self._remove(key)
82
+ return None
83
+
84
+ # Load data
85
+ data_path = self.data_dir / f"{key}.json"
86
+ if not data_path.exists():
87
+ # Index/data mismatch - clean up
88
+ self._remove(key)
89
+ return None
90
+
91
+ try:
92
+ with open(data_path) as f:
93
+ data = json.load(f)
94
+
95
+ # Reconstruct ContextItems
96
+ items = []
97
+ for item_data in data:
98
+ items.append(ContextItem(
99
+ id=item_data['id'],
100
+ source=item_data['source'],
101
+ title=item_data['title'],
102
+ summary=item_data['summary'],
103
+ excerpt=item_data.get('excerpt', ''),
104
+ relevance=item_data.get('relevance', 0.0),
105
+ age_days=item_data.get('age_days', 0.0),
106
+ metadata=item_data.get('metadata', {})
107
+ ))
108
+
109
+ return items
110
+ except Exception as e:
111
+ print(f"Warning: Failed to load cache entry {key}: {e}", file=sys.stderr)
112
+ self._remove(key)
113
+ return None
114
+
115
+ def set(self, library_id: str, query: str, items: List[ContextItem]):
116
+ """Cache query results."""
117
+ key = self._cache_key(library_id, query)
118
+
119
+ # Serialize items
120
+ items_data = []
121
+ for item in items:
122
+ items_data.append({
123
+ 'id': item.id,
124
+ 'source': item.source,
125
+ 'title': item.title,
126
+ 'summary': item.summary,
127
+ 'excerpt': item.excerpt,
128
+ 'relevance': item.relevance,
129
+ 'age_days': item.age_days,
130
+ 'metadata': item.metadata
131
+ })
132
+
133
+ # Write data
134
+ data_path = self.data_dir / f"{key}.json"
135
+ with open(data_path, 'w') as f:
136
+ json.dump(items_data, f, indent=2)
137
+
138
+ # Update index
139
+ self.index[key] = {
140
+ 'library_id': library_id,
141
+ 'query': query,
142
+ 'cached_at': datetime.now(timezone.utc).isoformat(),
143
+ 'item_count': len(items)
144
+ }
145
+
146
+ # Enforce max entries (LRU-style cleanup)
147
+ if len(self.index) > MAX_CACHE_ENTRIES:
148
+ self._evict_oldest()
149
+
150
+ self._save_index()
151
+
152
+ def _remove(self, key: str):
153
+ """Remove cache entry."""
154
+ # Remove from index
155
+ if key in self.index:
156
+ del self.index[key]
157
+ self._save_index()
158
+
159
+ # Remove data file
160
+ data_path = self.data_dir / f"{key}.json"
161
+ if data_path.exists():
162
+ data_path.unlink()
163
+
164
+ def _evict_oldest(self):
165
+ """Evict oldest 10% of entries."""
166
+ # Sort by cached_at
167
+ sorted_entries = sorted(
168
+ self.index.items(),
169
+ key=lambda x: x[1]['cached_at']
170
+ )
171
+
172
+ evict_count = max(1, len(sorted_entries) // 10)
173
+ for key, _ in sorted_entries[:evict_count]:
174
+ self._remove(key)
175
+
176
+ def clear(self):
177
+ """Clear entire cache."""
178
+ for key in list(self.index.keys()):
179
+ self._remove(key)
180
+
181
+
182
+ # Global cache instance
183
+ _cache = Context7Cache()
184
+
185
+
186
+ async def query(prompt: str, project: str = None) -> List[ContextItem]:
187
+ """
188
+ Query Context7 for relevant library documentation.
189
+
190
+ This adapter uses the Context7 MCP integration to fetch external library docs.
191
+
192
+ Strategy:
193
+ 1. Extract library names from prompt
194
+ 2. Check local cheatsheet store (hot tier — no MCP call needed)
195
+ 3. Resolve library IDs via Context7 (cached) for misses
196
+ 4. Query documentation (cached)
197
+ 5. Transform to ContextItems
198
+
199
+ Args:
200
+ prompt: User's query/prompt
201
+ project: Optional project context (unused for Context7)
202
+
203
+ Returns:
204
+ List of ContextItems with documentation snippets
205
+ """
206
+ items = []
207
+
208
+ # Extract potential library names from prompt
209
+ library_names = _extract_library_names(prompt)
210
+ if not library_names:
211
+ return items
212
+
213
+ # For each library, try to get docs
214
+ for lib_name in library_names[:3]: # Limit to 3 libraries
215
+ try:
216
+ # Try to get from cache first
217
+ cached = _cache.get(lib_name, prompt)
218
+ if cached is not None:
219
+ items.extend(cached)
220
+ continue
221
+
222
+ # Not cached - query Context7
223
+ lib_items = await _query_context7(lib_name, prompt)
224
+
225
+ # Cache results (even if empty)
226
+ _cache.set(lib_name, prompt, lib_items)
227
+
228
+ items.extend(lib_items)
229
+
230
+ except asyncio.TimeoutError:
231
+ print(f"Warning: Context7 query timeout for {lib_name}", file=sys.stderr)
232
+ except Exception as e:
233
+ print(f"Warning: Context7 query failed for {lib_name}: {e}", file=sys.stderr)
234
+
235
+ return items
236
+
237
+
238
+ async def _query_context7(library_name: str, query: str, timeout: float = 5.0) -> List[ContextItem]:
239
+ """
240
+ Query Context7 for a specific library.
241
+
242
+ This function interfaces with the Context7 MCP tools if available.
243
+ Falls back gracefully if MCP integration is not present.
244
+
245
+ Args:
246
+ library_name: Name of the library (e.g., "react", "express")
247
+ query: The user's query
248
+ timeout: Query timeout in seconds
249
+
250
+ Returns:
251
+ List of ContextItems from Context7 docs
252
+ """
253
+ items = []
254
+
255
+ # Check if Context7 MCP tools are available
256
+ try:
257
+ # Import at runtime to avoid hard dependency
258
+ # This would be the MCP integration point
259
+ # For now, we'll use a subprocess approach to call MCP tools
260
+
261
+ # Step 1: Resolve library ID
262
+ library_id = await asyncio.wait_for(
263
+ _resolve_library_id(library_name, query),
264
+ timeout=timeout / 2
265
+ )
266
+
267
+ if not library_id:
268
+ return items
269
+
270
+ # Step 2: Query docs with library ID
271
+ docs = await asyncio.wait_for(
272
+ _query_docs(library_id, query),
273
+ timeout=timeout / 2
274
+ )
275
+
276
+ # Step 3: Transform to ContextItems
277
+ for idx, doc in enumerate(docs[:5]): # Limit to 5 results
278
+ items.append(ContextItem(
279
+ id=f"context7:{library_id}:{idx}",
280
+ source="context7",
281
+ title=doc.get('title', f"{library_name} Documentation"),
282
+ summary=doc.get('summary', '')[:200],
283
+ excerpt=doc.get('content', '')[:500],
284
+ relevance=doc.get('score', 0.7),
285
+ age_days=0.0, # External docs are current
286
+ metadata={
287
+ 'library_id': library_id,
288
+ 'library_name': library_name,
289
+ 'url': doc.get('url', ''),
290
+ 'source_type': 'external_docs',
291
+ }
292
+ ))
293
+
294
+ except asyncio.TimeoutError:
295
+ raise
296
+ except ImportError:
297
+ # MCP tools not available - graceful degradation
298
+ pass # fail open: MCP tools optional
299
+ except Exception as e:
300
+ # Log but don't fail
301
+ print(f"Context7 query error: {e}", file=sys.stderr)
302
+
303
+ return items
304
+
305
+
306
+ async def _resolve_library_id(library_name: str, query: str) -> Optional[str]:
307
+ """
308
+ Resolve library name to Context7 library ID.
309
+
310
+ Uses the Context7 MCP tool: resolve-library-id
311
+
312
+ Returns:
313
+ Library ID (e.g., "/vercel/next.js") or None
314
+ """
315
+ try:
316
+ # Call Claude Code to invoke MCP tool via subprocess
317
+ # In production, this would use the MCP client directly
318
+ # For now, simulate with a known mapping
319
+
320
+ # Common library mappings (fallback)
321
+ library_map = {
322
+ 'react': '/facebook/react',
323
+ 'nextjs': '/vercel/next.js',
324
+ 'next': '/vercel/next.js',
325
+ 'express': '/expressjs/express',
326
+ 'fastapi': '/tiangolo/fastapi',
327
+ 'django': '/django/django',
328
+ 'flask': '/pallets/flask',
329
+ 'vue': '/vuejs/core',
330
+ 'angular': '/angular/angular',
331
+ 'svelte': '/sveltejs/svelte',
332
+ }
333
+
334
+ normalized = library_name.lower().replace('.js', '').replace('-', '')
335
+ return library_map.get(normalized)
336
+
337
+ except Exception as e:
338
+ print(f"Library ID resolution failed for {library_name}: {e}", file=sys.stderr)
339
+ return None
340
+
341
+
342
+ async def _query_docs(library_id: str, query: str) -> List[Dict[str, Any]]:
343
+ """
344
+ Query Context7 documentation for a library ID.
345
+
346
+ Uses the Context7 MCP tool: query-docs
347
+
348
+ Returns:
349
+ List of documentation snippets with metadata
350
+ """
351
+ try:
352
+ # In production, this would call the actual MCP tool
353
+ # For now, return empty list (graceful degradation)
354
+ # The MCP integration would happen at the hook level
355
+ return []
356
+
357
+ except Exception as e:
358
+ print(f"Doc query failed for {library_id}: {e}", file=sys.stderr)
359
+ return []
360
+
361
+
362
+ def _extract_library_names(prompt: str) -> List[str]:
363
+ """
364
+ Extract potential library/framework names from prompt.
365
+
366
+ Uses heuristics to identify references to external libraries:
367
+ - Common library names
368
+ - Package manager patterns (npm install X, pip install X)
369
+ - Import statements
370
+
371
+ Args:
372
+ prompt: User's query text
373
+
374
+ Returns:
375
+ List of potential library names
376
+ """
377
+ import re
378
+
379
+ libraries = []
380
+ prompt_lower = prompt.lower()
381
+
382
+ # Pattern 1: Explicit library mentions with common keywords
383
+ library_patterns = [
384
+ r'\b(react|vue|angular|svelte|next(?:js)?|nuxt)\b',
385
+ r'\b(express|fastapi|django|flask|rails|spring)\b',
386
+ r'\b(mongodb|postgres|mysql|redis|elasticsearch)\b',
387
+ r'\b(typescript|python|java|rust|go)\b',
388
+ r'\b(jest|pytest|mocha|cypress|playwright)\b',
389
+ r'\b(webpack|vite|rollup|esbuild|parcel)\b',
390
+ ]
391
+
392
+ for pattern in library_patterns:
393
+ matches = re.findall(pattern, prompt_lower)
394
+ libraries.extend(matches)
395
+
396
+ # Pattern 2: Package manager install commands
397
+ install_patterns = [
398
+ r'npm install\s+(@?[\w-]+(?:/[\w-]+)?)',
399
+ r'pip install\s+([\w-]+)',
400
+ r'yarn add\s+(@?[\w-]+(?:/[\w-]+)?)',
401
+ ]
402
+
403
+ for pattern in install_patterns:
404
+ matches = re.findall(pattern, prompt_lower)
405
+ libraries.extend(matches)
406
+
407
+ # Pattern 3: Import statements
408
+ import_patterns = [
409
+ r'from\s+([\w-]+)\s+import',
410
+ r'import\s+([\w-]+)',
411
+ r'require\([\'"](@?[\w-]+(?:/[\w-]+)?)[\'"]',
412
+ ]
413
+
414
+ for pattern in import_patterns:
415
+ matches = re.findall(pattern, prompt)
416
+ libraries.extend(matches)
417
+
418
+ # Deduplicate and clean
419
+ unique_libs = []
420
+ seen = set()
421
+ for lib in libraries:
422
+ # Clean up library name
423
+ lib = lib.strip().lower()
424
+
425
+ # Skip built-ins and common false positives
426
+ skip_list = {'os', 'sys', 'json', 'time', 're', 'math', 'from', 'import'}
427
+ if lib in skip_list or len(lib) < 2:
428
+ continue
429
+
430
+ if lib not in seen:
431
+ seen.add(lib)
432
+ unique_libs.append(lib)
433
+
434
+ return unique_libs[:5] # Limit to 5 libraries
435
+
436
+
437
+ # Public API
438
+ __all__ = ['query', 'Context7Cache']