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,559 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ _domain_store.py — DomainStore: per-domain local JSON storage with integration-discovery routing.
4
+
5
+ The standard storage interface for all domain scripts.
6
+ Local JSON is the canonical store. External tools (Linear MCP, Jira MCP, Notion MCP, etc.)
7
+ are resolved via integration-discovery and used when configured and authenticated.
8
+
9
+ Storage paths:
10
+ Local: ~/.something-wicked/wicked-garden/local/{domain}/{source}/{id}.json
11
+
12
+ Usage:
13
+ from _domain_store import DomainStore
14
+
15
+ ds = DomainStore("wicked-garden:mem")
16
+ items = ds.list("memories", project="my-project")
17
+ item = ds.get("memories", "abc123")
18
+ new = ds.create("memories", {"title": "...", "content": "..."})
19
+ ds.update("memories", "abc123", {"title": "new title"})
20
+ ds.delete("memories", "abc123")
21
+
22
+ # For truly ephemeral files (caches, temp session state) only:
23
+ from _domain_store import get_local_path
24
+ cache_dir = get_local_path("wicked-smaht", "cache", "context7")
25
+
26
+ hook_mode=True:
27
+ When True, skips integration-discovery entirely and operates local-only.
28
+ Use this from hook scripts to stay within the 5s timing budget.
29
+
30
+ _skip_discovery=True:
31
+ When True, skips integration-discovery. Used internally by the integration
32
+ resolver when it writes preferences via MemoryStore to avoid circular init.
33
+ """
34
+ from __future__ import annotations
35
+
36
+ import json
37
+ import os
38
+ import sys
39
+ import uuid
40
+ from datetime import datetime, timezone
41
+ from pathlib import Path
42
+ from typing import Any
43
+
44
+ # ---------------------------------------------------------------------------
45
+ # Paths (shared with _storage.py — same local JSON location)
46
+ # ---------------------------------------------------------------------------
47
+
48
+ try:
49
+ from _paths import get_project_root
50
+ _LOCAL_ROOT = get_project_root()
51
+ except ImportError:
52
+ _LOCAL_ROOT = Path.home() / ".something-wicked" / "wicked-garden" / "local"
53
+
54
+ # ---------------------------------------------------------------------------
55
+ # Domain MCP Pattern Registry
56
+ #
57
+ # Maps domain names to keyword patterns that identify compatible MCP servers.
58
+ # Used by integration-discovery to find external tools for each domain.
59
+ # Matching is case-insensitive substring search.
60
+ # Domains not listed here skip discovery and go directly to local JSON.
61
+ # ---------------------------------------------------------------------------
62
+
63
+ DOMAIN_MCP_PATTERNS: dict[str, list[str]] = {
64
+ "wicked-garden:mem": [
65
+ "notion", "confluence", "obsidian", "memory",
66
+ "knowledge", "wiki", "coda",
67
+ ],
68
+ "wicked-jam": [
69
+ "miro", "figjam", "mural", "whiteboard",
70
+ "figma", "brainstorm",
71
+ ],
72
+ "wicked-crew": ["jira", "linear", "github", "rally", "ado", "azure-devops", "project"],
73
+ "wicked-garden:search": ["elasticsearch", "algolia", "typesense", "search"],
74
+ # wicked-smaht, wicked-qe, wicked-patch: local-only (no MCP patterns)
75
+ }
76
+
77
+
78
+ # ---------------------------------------------------------------------------
79
+ # Public path helpers — delegate to _paths.py
80
+ # ---------------------------------------------------------------------------
81
+
82
+
83
+ def get_local_path(domain: str, *subpath: str) -> Path:
84
+ """Delegate to _paths.get_local_path — see _paths.py for docs.
85
+
86
+ Returns a directory path under the wicked-garden local root,
87
+ creating it if it does not exist.
88
+
89
+ Example:
90
+ get_local_path("wicked-crew", "projects")
91
+ # → ~/.something-wicked/wicked-garden/local/wicked-crew/projects/
92
+ """
93
+ try:
94
+ sys.path.insert(0, str(Path(__file__).parent))
95
+ from _paths import get_local_path as _glp
96
+ return _glp(domain, *subpath)
97
+ except ImportError:
98
+ # Inline fallback if _paths.py is not present
99
+ p = _LOCAL_ROOT / domain
100
+ for part in subpath:
101
+ p = p / part
102
+ p.mkdir(parents=True, exist_ok=True)
103
+ return p
104
+
105
+
106
+ def get_local_file(domain: str, *subpath: str) -> Path:
107
+ """Delegate to _paths.get_local_file — see _paths.py for docs.
108
+
109
+ Returns a file path under the wicked-garden local root.
110
+ Parent directories are created automatically. Does not create the file.
111
+
112
+ Example:
113
+ get_local_file("wicked-garden:search", "unified_search.db")
114
+ # → ~/.something-wicked/wicked-garden/local/wicked-garden:search/unified_search.db
115
+ """
116
+ try:
117
+ sys.path.insert(0, str(Path(__file__).parent))
118
+ from _paths import get_local_file as _glf
119
+ return _glf(domain, *subpath)
120
+ except ImportError:
121
+ # Inline fallback if _paths.py is not present
122
+ p = _LOCAL_ROOT / domain
123
+ for part in subpath:
124
+ p = p / part
125
+ p.parent.mkdir(parents=True, exist_ok=True)
126
+ return p
127
+
128
+
129
+ # ---------------------------------------------------------------------------
130
+ # DomainStore
131
+ # ---------------------------------------------------------------------------
132
+
133
+
134
+ class DomainStore:
135
+ """Per-domain local JSON storage with integration-discovery routing.
136
+
137
+ Initialization (once per domain per script invocation):
138
+ 1. Load cached tool selection from SessionState.integration_tools[domain]
139
+ 2. If no cache: run _init_routing() to discover + resolve external tool
140
+ 3. Store result back to SessionState for the session lifetime
141
+
142
+ CRUD API:
143
+ list(source, **params) -> list[dict]
144
+ get(source, id) -> dict | None
145
+ create(source, payload) -> dict
146
+ update(source, id, diff) -> dict | None
147
+ delete(source, id) -> bool
148
+ search(source, q, **params) -> list[dict] (delegates to list with q in params)
149
+
150
+ Routing:
151
+ - If an external tool is resolved: delegate to ExternalToolAdapter first,
152
+ fall back to local JSON on None return.
153
+ - hook_mode=True or _skip_discovery=True: local JSON only, no discovery.
154
+ - Domains not in DOMAIN_MCP_PATTERNS: local JSON only.
155
+ """
156
+
157
+ def __init__(
158
+ self,
159
+ domain: str,
160
+ *,
161
+ hook_mode: bool = False,
162
+ _skip_discovery: bool = False,
163
+ ) -> None:
164
+ """
165
+ Args:
166
+ domain: Plugin domain, e.g. "wicked-garden:mem", "wicked-crew".
167
+ hook_mode: Pass True from hook scripts. Skips integration-discovery
168
+ to stay within the 5s hook timing budget.
169
+ _skip_discovery: Internal flag. Pass True from integration resolver when
170
+ creating a MemoryStore to prevent circular initialization.
171
+ """
172
+ self._domain = domain
173
+ self._hook_mode = hook_mode
174
+ self._skip_discovery = _skip_discovery
175
+ self._external: Any | None = None # ExternalToolAdapter, wired in Task 1.4
176
+ self._init_routing()
177
+
178
+ # ------------------------------------------------------------------
179
+ # Routing initialization
180
+ # ------------------------------------------------------------------
181
+
182
+ def _init_routing(self) -> None:
183
+ """Load or discover the external tool for this domain.
184
+
185
+ 1. Skip entirely when hook_mode or _skip_discovery is True.
186
+ 2. Check SessionState.integration_tools[domain] cache first (<5ms).
187
+ 3. If cache miss: call resolve_tool() — runs discovery.
188
+ 4. Cache the result in SessionState for the session lifetime.
189
+ 5. If resolved tool != "local" and != None: instantiate adapter via
190
+ from_tool_name() and assign to self._external.
191
+
192
+ Imports are lazy (inside this method) to avoid circular imports at
193
+ module load time. Any import failure causes silent local-only fallback.
194
+ """
195
+ # hooks and circular-init callers always go local
196
+ if self._hook_mode or self._skip_discovery:
197
+ return
198
+
199
+ # Domains not in the pattern registry skip discovery entirely
200
+ if self._domain not in DOMAIN_MCP_PATTERNS:
201
+ return
202
+
203
+ tool_name: str | None = None
204
+
205
+ # ── Step 1: check session cache ──────────────────────────────────────
206
+ try:
207
+ sys.path.insert(0, str(Path(__file__).parent))
208
+ from _session import SessionState
209
+
210
+ state = SessionState.load()
211
+ cached = (state.integration_tools or {}).get(self._domain)
212
+ if cached is not None:
213
+ # Cache hit — use the stored value directly
214
+ tool_name = cached if cached != "local" else None
215
+ else:
216
+ # ── Step 2: cache miss — run discovery ───────────────────────
217
+ tool_name = self._discover_tool()
218
+
219
+ # ── Step 3: cache in SessionState ────────────────────────────
220
+ tools = dict(state.integration_tools or {})
221
+ tools[self._domain] = tool_name if tool_name else "local"
222
+ state.update(integration_tools=tools)
223
+ except Exception:
224
+ # SessionState unavailable (e.g. no TMPDIR, corrupted file) —
225
+ # run discovery without caching; fail open on any error.
226
+ try:
227
+ tool_name = self._discover_tool()
228
+ except Exception:
229
+ tool_name = None
230
+
231
+ # ── Step 4: instantiate adapter ──────────────────────────────────────
232
+ if tool_name and tool_name != "local":
233
+ try:
234
+ from _adapters import from_tool_name
235
+
236
+ self._external = from_tool_name(tool_name)
237
+ except Exception:
238
+ self._external = None # import failure → local only
239
+
240
+ def _discover_tool(self) -> str | None:
241
+ """Run integration-resolver discovery for this domain.
242
+
243
+ Returns the tool name string or None for local-only. Imported lazily
244
+ to avoid circular imports (_integration_resolver imports _domain_store).
245
+ """
246
+ try:
247
+ from _integration_resolver import resolve_tool
248
+
249
+ return resolve_tool(self._domain, hook_mode=False)
250
+ except Exception:
251
+ return None
252
+
253
+ # ------------------------------------------------------------------
254
+ # Read operations
255
+ # ------------------------------------------------------------------
256
+
257
+ def list(self, source: str, **params) -> list[dict]:
258
+ """List records for a source, with optional filter params.
259
+
260
+ Returns:
261
+ List of record dicts. Empty list on any error.
262
+
263
+ Delegates to external tool first (when resolved); falls back to local JSON.
264
+ """
265
+ if self._external is not None:
266
+ try:
267
+ result = self._external.list(source, **params)
268
+ if result is not None:
269
+ return result
270
+ except Exception:
271
+ pass # fall through to local
272
+
273
+ return self._local_list(source, params)
274
+
275
+ def search(self, source: str, q: str, **params) -> list[dict]:
276
+ """Search records — delegates to list() with q in params.
277
+
278
+ Falls back to local token-based search (title, content, summary, description).
279
+
280
+ Args:
281
+ source: Source name (e.g. "memories")
282
+ q: Search query string
283
+ **params: Additional filter params (type, project, etc.)
284
+ """
285
+ return self.list(source, q=q, **params)
286
+
287
+ def get(self, source: str, id: str) -> dict | None:
288
+ """Fetch a single record by ID.
289
+
290
+ Returns:
291
+ Record dict, or None if not found.
292
+ """
293
+ if self._external is not None:
294
+ try:
295
+ result = self._external.get(source, id)
296
+ if result is not None:
297
+ return result
298
+ except Exception:
299
+ pass # fall through to local
300
+
301
+ return self._local_get(source, id)
302
+
303
+ # ------------------------------------------------------------------
304
+ # Event emission (fire-and-forget)
305
+ # ------------------------------------------------------------------
306
+
307
+ def _emit_event(self, action: str, source: str, record_id: str | None = None,
308
+ payload: dict | None = None, tags: list[str] | None = None) -> None:
309
+ """Emit an event to the unified event log. Never raises.
310
+
311
+ Emits only safe metadata (id, timestamps, action) — not the full record
312
+ payload, to avoid replicating sensitive data into the FTS-indexed event log.
313
+ Callers needing full payload in events should call EventStore.append() directly.
314
+ """
315
+ try:
316
+ from _event_store import EventStore
317
+ EventStore.ensure_schema()
318
+
319
+ # Auto-resolve project_id from session state
320
+ project_id = None
321
+ try:
322
+ from _session import SessionState
323
+ state = SessionState.load()
324
+ project_id = getattr(state, "active_project", None)
325
+ except Exception:
326
+ pass # fail open
327
+
328
+ # Emit safe metadata only — strip sensitive fields from payload
329
+ safe_payload = None
330
+ if payload is not None:
331
+ safe_payload = {
332
+ k: v for k, v in payload.items()
333
+ if k in ("id", "name", "title", "type", "status", "phase",
334
+ "created_at", "updated_at", "deleted_at", "tags",
335
+ "complexity_score", "signals_detected")
336
+ }
337
+
338
+ EventStore.append(
339
+ domain=self._domain,
340
+ action=f"{source}.{action}",
341
+ source=source,
342
+ record_id=record_id,
343
+ payload=safe_payload if safe_payload else None,
344
+ project_id=project_id,
345
+ tags=tags,
346
+ )
347
+ except Exception:
348
+ pass # fire-and-forget — never break domain operations
349
+
350
+ # ------------------------------------------------------------------
351
+ # Write operations
352
+ # ------------------------------------------------------------------
353
+
354
+ def create(self, source: str, payload: dict) -> dict | None:
355
+ """Create a new record.
356
+
357
+ Returns:
358
+ Created record dict, or None on failure.
359
+
360
+ When an external tool is resolved, delegates to it first. On success,
361
+ also writes to local JSON (external tool is the ID authority when used).
362
+ Falls back to local JSON with auto-generated UUID on any failure.
363
+ """
364
+ record = dict(payload)
365
+ record.setdefault("created_at", _now())
366
+ record.setdefault("updated_at", _now())
367
+
368
+ if self._external is not None:
369
+ try:
370
+ result = self._external.create(source, record)
371
+ if result is not None:
372
+ # Use external-tool-assigned ID as canonical ID
373
+ if result.get("id"):
374
+ record["id"] = result["id"]
375
+ elif "id" not in record:
376
+ record["id"] = str(uuid.uuid4())
377
+ self._local_write(source, record["id"], record)
378
+ self._emit_event("created", source, record["id"], record)
379
+ return record
380
+ except Exception:
381
+ pass # fall through to local
382
+
383
+ # Local path: generate UUID and write
384
+ if "id" not in record:
385
+ record["id"] = str(uuid.uuid4())
386
+ self._local_write(source, record["id"], record)
387
+ self._emit_event("created", source, record["id"], record)
388
+ return record
389
+
390
+ def update(self, source: str, id: str, diff: dict) -> dict | None:
391
+ """Patch an existing record with the fields in diff.
392
+
393
+ Returns:
394
+ Updated record dict, or None if not found.
395
+ """
396
+ if self._external is not None:
397
+ try:
398
+ result = self._external.update(source, id, diff)
399
+ if result is not None:
400
+ # Also update local copy
401
+ existing = self._local_get(source, id)
402
+ if existing:
403
+ existing.update(diff)
404
+ existing["updated_at"] = _now()
405
+ self._local_write(source, id, existing)
406
+ return result
407
+ except Exception:
408
+ pass # fall through to local
409
+
410
+ # Local path: read-modify-write
411
+ existing = self._local_get(source, id)
412
+ if existing is None:
413
+ return None
414
+
415
+ existing.update(diff)
416
+ existing["updated_at"] = _now()
417
+ self._local_write(source, id, existing)
418
+ self._emit_event("updated", source, id, diff)
419
+ return existing
420
+
421
+ def delete(self, source: str, id: str) -> bool:
422
+ """Delete a record (soft-delete: sets deleted=True locally).
423
+
424
+ Returns:
425
+ True if the record was found and removed/marked deleted.
426
+ """
427
+ if self._external is not None:
428
+ try:
429
+ result = self._external.delete(source, id)
430
+ if result is not None:
431
+ # Also soft-delete locally
432
+ existing = self._local_get(source, id)
433
+ if existing:
434
+ existing["deleted"] = True
435
+ existing["deleted_at"] = _now()
436
+ self._local_write(source, id, existing)
437
+ return bool(result)
438
+ except Exception:
439
+ pass # fall through to local
440
+
441
+ # Local path: soft-delete
442
+ existing = self._local_get(source, id)
443
+ if existing is None:
444
+ return False
445
+
446
+ existing["deleted"] = True
447
+ existing["deleted_at"] = _now()
448
+ self._local_write(source, id, existing)
449
+ self._emit_event("deleted", source, id)
450
+ return True
451
+
452
+ # ------------------------------------------------------------------
453
+ # Private: local file operations
454
+ # (local file operations)
455
+ # ------------------------------------------------------------------
456
+
457
+ def _local_dir(self, source: str) -> Path:
458
+ return _LOCAL_ROOT / self._domain / source
459
+
460
+ def _local_file(self, source: str, id: str) -> Path:
461
+ return self._local_dir(source) / f"{id}.json"
462
+
463
+ def _local_list(self, source: str, params: dict) -> list[dict]:
464
+ """Scan local JSON files and return non-deleted records matching params."""
465
+ source_dir = self._local_dir(source)
466
+ if not source_dir.exists():
467
+ return []
468
+
469
+ records: list[dict] = []
470
+ for json_file in sorted(source_dir.glob("*.json")):
471
+ try:
472
+ record = json.loads(json_file.read_text(encoding="utf-8"))
473
+ except (json.JSONDecodeError, OSError):
474
+ continue
475
+
476
+ # Skip soft-deleted records
477
+ if record.get("deleted"):
478
+ continue
479
+
480
+ # Apply simple equality filters from params
481
+ if not _matches_params(record, params):
482
+ continue
483
+
484
+ records.append(record)
485
+
486
+ return records
487
+
488
+ def _local_get(self, source: str, id: str) -> dict | None:
489
+ """Read a single local JSON file by ID."""
490
+ path = self._local_file(source, id)
491
+
492
+ if path.exists():
493
+ try:
494
+ record = json.loads(path.read_text(encoding="utf-8"))
495
+ if record.get("deleted"):
496
+ return None
497
+ return record
498
+ except (json.JSONDecodeError, OSError):
499
+ return None
500
+
501
+ return None
502
+
503
+ def _local_write(self, source: str, id: str, record: dict) -> None:
504
+ """Atomically write a record to its local JSON file."""
505
+ path = self._local_file(source, id)
506
+ path.parent.mkdir(parents=True, exist_ok=True)
507
+ tmp = path.with_suffix(".tmp")
508
+ try:
509
+ tmp.write_text(json.dumps(record, indent=2), encoding="utf-8")
510
+ os.replace(tmp, path)
511
+ except OSError as exc:
512
+ print(
513
+ f"[wicked-garden] Local write failed for {source}/{id}: {exc}",
514
+ file=sys.stderr,
515
+ )
516
+
517
+
518
+ # ---------------------------------------------------------------------------
519
+ # Helpers
520
+ # ---------------------------------------------------------------------------
521
+
522
+
523
+ def _matches_params(record: dict, params: dict) -> bool:
524
+ """Filter for local list queries.
525
+
526
+ Supports exact equality for most fields plus substring search for the
527
+ special ``q`` parameter (searches across title, content, summary,
528
+ description).
529
+
530
+ Copied from _storage.py to avoid import dependency.
531
+ """
532
+ for key, value in params.items():
533
+ if key == "q":
534
+ # Token-based search across text fields (all tokens must match)
535
+ text_fields = [
536
+ str(record.get(f, ""))
537
+ for f in ("title", "content", "summary", "description")
538
+ ]
539
+ # Include tags (may be a list)
540
+ tags_val = record.get("tags", [])
541
+ if isinstance(tags_val, list):
542
+ text_fields.append(" ".join(str(t) for t in tags_val))
543
+ elif tags_val:
544
+ text_fields.append(str(tags_val))
545
+ # Include search_tags if present
546
+ search_tags_val = record.get("search_tags", "")
547
+ if search_tags_val:
548
+ text_fields.append(str(search_tags_val))
549
+ searchable = " ".join(text_fields).lower()
550
+ tokens = str(value).lower().split()
551
+ if not all(tok in searchable for tok in tokens):
552
+ return False
553
+ elif record.get(key) != value:
554
+ return False
555
+ return True
556
+
557
+
558
+ def _now() -> str:
559
+ return datetime.now(timezone.utc).isoformat()