@accelerationguy/accel 1.0.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 (376) hide show
  1. package/CLAUDE.md +19 -0
  2. package/LICENSE +33 -0
  3. package/README.md +275 -0
  4. package/bin/install.js +661 -0
  5. package/docs/getting-started.md +164 -0
  6. package/docs/module-guide.md +139 -0
  7. package/modules/drive/LICENSE +21 -0
  8. package/modules/drive/PAUL-VS-GSD.md +171 -0
  9. package/modules/drive/README.md +555 -0
  10. package/modules/drive/assets/terminal.svg +67 -0
  11. package/modules/drive/bin/install.js +210 -0
  12. package/modules/drive/integration.js +76 -0
  13. package/modules/drive/package.json +38 -0
  14. package/modules/drive/src/commands/add-phase.md +36 -0
  15. package/modules/drive/src/commands/apply.md +83 -0
  16. package/modules/drive/src/commands/assumptions.md +37 -0
  17. package/modules/drive/src/commands/audit.md +57 -0
  18. package/modules/drive/src/commands/complete-milestone.md +36 -0
  19. package/modules/drive/src/commands/config.md +175 -0
  20. package/modules/drive/src/commands/consider-issues.md +41 -0
  21. package/modules/drive/src/commands/discover.md +48 -0
  22. package/modules/drive/src/commands/discuss-milestone.md +33 -0
  23. package/modules/drive/src/commands/discuss.md +34 -0
  24. package/modules/drive/src/commands/flows.md +73 -0
  25. package/modules/drive/src/commands/handoff.md +201 -0
  26. package/modules/drive/src/commands/help.md +525 -0
  27. package/modules/drive/src/commands/init.md +54 -0
  28. package/modules/drive/src/commands/map-codebase.md +34 -0
  29. package/modules/drive/src/commands/milestone.md +34 -0
  30. package/modules/drive/src/commands/pause.md +44 -0
  31. package/modules/drive/src/commands/plan-fix.md +216 -0
  32. package/modules/drive/src/commands/plan.md +36 -0
  33. package/modules/drive/src/commands/progress.md +138 -0
  34. package/modules/drive/src/commands/register.md +29 -0
  35. package/modules/drive/src/commands/remove-phase.md +37 -0
  36. package/modules/drive/src/commands/research-phase.md +209 -0
  37. package/modules/drive/src/commands/research.md +47 -0
  38. package/modules/drive/src/commands/resume.md +49 -0
  39. package/modules/drive/src/commands/status.md +78 -0
  40. package/modules/drive/src/commands/unify.md +87 -0
  41. package/modules/drive/src/commands/verify.md +60 -0
  42. package/modules/drive/src/references/checkpoints.md +234 -0
  43. package/modules/drive/src/references/context-management.md +219 -0
  44. package/modules/drive/src/references/git-strategy.md +206 -0
  45. package/modules/drive/src/references/loop-phases.md +254 -0
  46. package/modules/drive/src/references/plan-format.md +263 -0
  47. package/modules/drive/src/references/quality-principles.md +152 -0
  48. package/modules/drive/src/references/research-quality-control.md +247 -0
  49. package/modules/drive/src/references/sonarqube-integration.md +244 -0
  50. package/modules/drive/src/references/specialized-workflow-integration.md +186 -0
  51. package/modules/drive/src/references/subagent-criteria.md +179 -0
  52. package/modules/drive/src/references/tdd.md +219 -0
  53. package/modules/drive/src/references/work-units.md +161 -0
  54. package/modules/drive/src/rules/commands.md +108 -0
  55. package/modules/drive/src/rules/references.md +107 -0
  56. package/modules/drive/src/rules/style.md +123 -0
  57. package/modules/drive/src/rules/templates.md +51 -0
  58. package/modules/drive/src/rules/workflows.md +133 -0
  59. package/modules/drive/src/templates/CONTEXT.md +88 -0
  60. package/modules/drive/src/templates/DEBUG.md +164 -0
  61. package/modules/drive/src/templates/DISCOVERY.md +148 -0
  62. package/modules/drive/src/templates/HANDOFF.md +77 -0
  63. package/modules/drive/src/templates/ISSUES.md +93 -0
  64. package/modules/drive/src/templates/MILESTONES.md +167 -0
  65. package/modules/drive/src/templates/PLAN.md +328 -0
  66. package/modules/drive/src/templates/PROJECT.md +219 -0
  67. package/modules/drive/src/templates/RESEARCH.md +130 -0
  68. package/modules/drive/src/templates/ROADMAP.md +328 -0
  69. package/modules/drive/src/templates/SPECIAL-FLOWS.md +70 -0
  70. package/modules/drive/src/templates/STATE.md +210 -0
  71. package/modules/drive/src/templates/SUMMARY.md +221 -0
  72. package/modules/drive/src/templates/UAT-ISSUES.md +139 -0
  73. package/modules/drive/src/templates/codebase/architecture.md +259 -0
  74. package/modules/drive/src/templates/codebase/concerns.md +329 -0
  75. package/modules/drive/src/templates/codebase/conventions.md +311 -0
  76. package/modules/drive/src/templates/codebase/integrations.md +284 -0
  77. package/modules/drive/src/templates/codebase/stack.md +190 -0
  78. package/modules/drive/src/templates/codebase/structure.md +287 -0
  79. package/modules/drive/src/templates/codebase/testing.md +484 -0
  80. package/modules/drive/src/templates/config.md +181 -0
  81. package/modules/drive/src/templates/milestone-archive.md +236 -0
  82. package/modules/drive/src/templates/milestone-context.md +190 -0
  83. package/modules/drive/src/templates/paul-json.md +147 -0
  84. package/modules/drive/src/vector-config/PAUL +26 -0
  85. package/modules/drive/src/vector-config/PAUL.manifest +11 -0
  86. package/modules/drive/src/workflows/apply-phase.md +393 -0
  87. package/modules/drive/src/workflows/audit-plan.md +344 -0
  88. package/modules/drive/src/workflows/complete-milestone.md +479 -0
  89. package/modules/drive/src/workflows/configure-special-flows.md +283 -0
  90. package/modules/drive/src/workflows/consider-issues.md +172 -0
  91. package/modules/drive/src/workflows/create-milestone.md +268 -0
  92. package/modules/drive/src/workflows/debug.md +292 -0
  93. package/modules/drive/src/workflows/discovery.md +187 -0
  94. package/modules/drive/src/workflows/discuss-milestone.md +245 -0
  95. package/modules/drive/src/workflows/discuss-phase.md +231 -0
  96. package/modules/drive/src/workflows/init-project.md +698 -0
  97. package/modules/drive/src/workflows/map-codebase.md +459 -0
  98. package/modules/drive/src/workflows/pause-work.md +259 -0
  99. package/modules/drive/src/workflows/phase-assumptions.md +181 -0
  100. package/modules/drive/src/workflows/plan-phase.md +385 -0
  101. package/modules/drive/src/workflows/quality-gate.md +263 -0
  102. package/modules/drive/src/workflows/register-manifest.md +107 -0
  103. package/modules/drive/src/workflows/research.md +241 -0
  104. package/modules/drive/src/workflows/resume-project.md +200 -0
  105. package/modules/drive/src/workflows/roadmap-management.md +334 -0
  106. package/modules/drive/src/workflows/transition-phase.md +368 -0
  107. package/modules/drive/src/workflows/unify-phase.md +290 -0
  108. package/modules/drive/src/workflows/verify-work.md +241 -0
  109. package/modules/forge/README.md +281 -0
  110. package/modules/forge/bin/install.js +200 -0
  111. package/modules/forge/package.json +32 -0
  112. package/modules/forge/skillsmith/rules/checklists-rules.md +42 -0
  113. package/modules/forge/skillsmith/rules/context-rules.md +43 -0
  114. package/modules/forge/skillsmith/rules/entry-point-rules.md +44 -0
  115. package/modules/forge/skillsmith/rules/frameworks-rules.md +43 -0
  116. package/modules/forge/skillsmith/rules/tasks-rules.md +52 -0
  117. package/modules/forge/skillsmith/rules/templates-rules.md +43 -0
  118. package/modules/forge/skillsmith/skillsmith.md +82 -0
  119. package/modules/forge/skillsmith/tasks/audit.md +277 -0
  120. package/modules/forge/skillsmith/tasks/discover.md +145 -0
  121. package/modules/forge/skillsmith/tasks/distill.md +276 -0
  122. package/modules/forge/skillsmith/tasks/scaffold.md +349 -0
  123. package/modules/forge/specs/checklists.md +193 -0
  124. package/modules/forge/specs/context.md +223 -0
  125. package/modules/forge/specs/entry-point.md +320 -0
  126. package/modules/forge/specs/frameworks.md +228 -0
  127. package/modules/forge/specs/rules.md +245 -0
  128. package/modules/forge/specs/tasks.md +344 -0
  129. package/modules/forge/specs/templates.md +335 -0
  130. package/modules/forge/terminal.svg +70 -0
  131. package/modules/ignition/README.md +245 -0
  132. package/modules/ignition/bin/install.js +184 -0
  133. package/modules/ignition/checklists/planning-quality.md +55 -0
  134. package/modules/ignition/data/application/config.md +21 -0
  135. package/modules/ignition/data/application/guide.md +51 -0
  136. package/modules/ignition/data/application/skill-loadout.md +11 -0
  137. package/modules/ignition/data/campaign/config.md +18 -0
  138. package/modules/ignition/data/campaign/guide.md +36 -0
  139. package/modules/ignition/data/campaign/skill-loadout.md +10 -0
  140. package/modules/ignition/data/client/config.md +18 -0
  141. package/modules/ignition/data/client/guide.md +36 -0
  142. package/modules/ignition/data/client/skill-loadout.md +11 -0
  143. package/modules/ignition/data/utility/config.md +18 -0
  144. package/modules/ignition/data/utility/guide.md +31 -0
  145. package/modules/ignition/data/utility/skill-loadout.md +8 -0
  146. package/modules/ignition/data/workflow/config.md +19 -0
  147. package/modules/ignition/data/workflow/guide.md +41 -0
  148. package/modules/ignition/data/workflow/skill-loadout.md +10 -0
  149. package/modules/ignition/integration.js +54 -0
  150. package/modules/ignition/package.json +35 -0
  151. package/modules/ignition/seed.md +81 -0
  152. package/modules/ignition/tasks/add-type.md +164 -0
  153. package/modules/ignition/tasks/graduate.md +182 -0
  154. package/modules/ignition/tasks/ideate.md +221 -0
  155. package/modules/ignition/tasks/launch.md +137 -0
  156. package/modules/ignition/tasks/status.md +71 -0
  157. package/modules/ignition/templates/planning-application.md +193 -0
  158. package/modules/ignition/templates/planning-campaign.md +138 -0
  159. package/modules/ignition/templates/planning-client.md +149 -0
  160. package/modules/ignition/templates/planning-utility.md +112 -0
  161. package/modules/ignition/templates/planning-workflow.md +125 -0
  162. package/modules/ignition/terminal.svg +74 -0
  163. package/modules/mission-control/CONTEXT-CONTINUITY-SPEC.md +293 -0
  164. package/modules/mission-control/CONTEXT-ENGINEERING-GUIDE.md +282 -0
  165. package/modules/mission-control/README.md +91 -0
  166. package/modules/mission-control/assets/terminal.svg +80 -0
  167. package/modules/mission-control/examples/entities.example.json +133 -0
  168. package/modules/mission-control/examples/projects.example.json +318 -0
  169. package/modules/mission-control/examples/state.example.json +183 -0
  170. package/modules/mission-control/examples/vector.example.json +245 -0
  171. package/modules/mission-control/mission-control/checklists/install-verification.md +46 -0
  172. package/modules/mission-control/mission-control/frameworks/framework-registry.md +83 -0
  173. package/modules/mission-control/mission-control/mission-control.md +83 -0
  174. package/modules/mission-control/mission-control/tasks/insights.md +73 -0
  175. package/modules/mission-control/mission-control/tasks/install.md +194 -0
  176. package/modules/mission-control/mission-control/tasks/status.md +125 -0
  177. package/modules/mission-control/schemas/entities.schema.json +89 -0
  178. package/modules/mission-control/schemas/projects.schema.json +221 -0
  179. package/modules/mission-control/schemas/state.schema.json +108 -0
  180. package/modules/mission-control/schemas/vector.schema.json +200 -0
  181. package/modules/momentum/README.md +678 -0
  182. package/modules/momentum/bin/install.js +563 -0
  183. package/modules/momentum/integration.js +131 -0
  184. package/modules/momentum/package.json +42 -0
  185. package/modules/momentum/schemas/entities.schema.json +89 -0
  186. package/modules/momentum/schemas/projects.schema.json +221 -0
  187. package/modules/momentum/schemas/state.schema.json +108 -0
  188. package/modules/momentum/src/commands/audit-claude-md.md +31 -0
  189. package/modules/momentum/src/commands/audit.md +33 -0
  190. package/modules/momentum/src/commands/groom.md +35 -0
  191. package/modules/momentum/src/commands/history.md +27 -0
  192. package/modules/momentum/src/commands/pulse.md +33 -0
  193. package/modules/momentum/src/commands/scaffold.md +33 -0
  194. package/modules/momentum/src/commands/status.md +28 -0
  195. package/modules/momentum/src/commands/surface-convert.md +35 -0
  196. package/modules/momentum/src/commands/surface-create.md +34 -0
  197. package/modules/momentum/src/commands/surface-list.md +27 -0
  198. package/modules/momentum/src/commands/vector-hygiene.md +33 -0
  199. package/modules/momentum/src/framework/context/momentum-principles.md +71 -0
  200. package/modules/momentum/src/framework/frameworks/audit-strategies.md +53 -0
  201. package/modules/momentum/src/framework/frameworks/satellite-registration.md +44 -0
  202. package/modules/momentum/src/framework/tasks/audit-claude-md.md +68 -0
  203. package/modules/momentum/src/framework/tasks/audit.md +64 -0
  204. package/modules/momentum/src/framework/tasks/groom.md +164 -0
  205. package/modules/momentum/src/framework/tasks/history.md +34 -0
  206. package/modules/momentum/src/framework/tasks/pulse.md +83 -0
  207. package/modules/momentum/src/framework/tasks/scaffold.md +202 -0
  208. package/modules/momentum/src/framework/tasks/status.md +35 -0
  209. package/modules/momentum/src/framework/tasks/surface-convert.md +143 -0
  210. package/modules/momentum/src/framework/tasks/surface-create.md +184 -0
  211. package/modules/momentum/src/framework/tasks/surface-list.md +42 -0
  212. package/modules/momentum/src/framework/tasks/vector-hygiene.md +160 -0
  213. package/modules/momentum/src/framework/templates/workspace-json.md +96 -0
  214. package/modules/momentum/src/hooks/_template.py +129 -0
  215. package/modules/momentum/src/hooks/active-hook.py +178 -0
  216. package/modules/momentum/src/hooks/backlog-hook.py +115 -0
  217. package/modules/momentum/src/hooks/mission-control-insights.py +169 -0
  218. package/modules/momentum/src/hooks/momentum-pulse-check.py +351 -0
  219. package/modules/momentum/src/hooks/operator.py +53 -0
  220. package/modules/momentum/src/hooks/psmm-injector.py +67 -0
  221. package/modules/momentum/src/hooks/satellite-detection.py +248 -0
  222. package/modules/momentum/src/packages/momentum-mcp/index.js +119 -0
  223. package/modules/momentum/src/packages/momentum-mcp/package.json +10 -0
  224. package/modules/momentum/src/packages/momentum-mcp/tools/entities.js +226 -0
  225. package/modules/momentum/src/packages/momentum-mcp/tools/operator.js +106 -0
  226. package/modules/momentum/src/packages/momentum-mcp/tools/projects.js +322 -0
  227. package/modules/momentum/src/packages/momentum-mcp/tools/psmm.js +206 -0
  228. package/modules/momentum/src/packages/momentum-mcp/tools/state.js +199 -0
  229. package/modules/momentum/src/packages/momentum-mcp/tools/surfaces.js +404 -0
  230. package/modules/momentum/src/skill/momentum.md +111 -0
  231. package/modules/momentum/src/tasks/groom.md +164 -0
  232. package/modules/momentum/src/templates/operator.json +66 -0
  233. package/modules/momentum/src/templates/workspace.json +111 -0
  234. package/modules/momentum/terminal.svg +77 -0
  235. package/modules/radar/README.md +1552 -0
  236. package/modules/radar/commands/audit.md +233 -0
  237. package/modules/radar/commands/guardrails.md +194 -0
  238. package/modules/radar/commands/init.md +207 -0
  239. package/modules/radar/commands/playbook.md +176 -0
  240. package/modules/radar/commands/remediate.md +156 -0
  241. package/modules/radar/commands/report.md +172 -0
  242. package/modules/radar/commands/resume.md +176 -0
  243. package/modules/radar/commands/status.md +148 -0
  244. package/modules/radar/commands/transform.md +205 -0
  245. package/modules/radar/commands/validate.md +177 -0
  246. package/modules/radar/docs/ARCHITECTURE.md +336 -0
  247. package/modules/radar/docs/GETTING-STARTED.md +287 -0
  248. package/modules/radar/docs/standards/agents.md +197 -0
  249. package/modules/radar/docs/standards/commands.md +250 -0
  250. package/modules/radar/docs/standards/domains.md +191 -0
  251. package/modules/radar/docs/standards/personas.md +211 -0
  252. package/modules/radar/docs/standards/rules.md +218 -0
  253. package/modules/radar/docs/standards/runtime.md +445 -0
  254. package/modules/radar/docs/standards/schemas.md +269 -0
  255. package/modules/radar/docs/standards/tools.md +273 -0
  256. package/modules/radar/docs/standards/workflows.md +254 -0
  257. package/modules/radar/docs/terminal.svg +72 -0
  258. package/modules/radar/docs/validation/convention-compliance-report.md +183 -0
  259. package/modules/radar/docs/validation/cross-reference-report.md +195 -0
  260. package/modules/radar/docs/validation/validation-summary.md +118 -0
  261. package/modules/radar/docs/validation/version-manifest.yaml +363 -0
  262. package/modules/radar/install.sh +711 -0
  263. package/modules/radar/integration.js +53 -0
  264. package/modules/radar/src/core/agents/architect.md +25 -0
  265. package/modules/radar/src/core/agents/compliance-officer.md +25 -0
  266. package/modules/radar/src/core/agents/data-engineer.md +25 -0
  267. package/modules/radar/src/core/agents/devils-advocate.md +22 -0
  268. package/modules/radar/src/core/agents/performance-engineer.md +25 -0
  269. package/modules/radar/src/core/agents/principal-engineer.md +23 -0
  270. package/modules/radar/src/core/agents/reality-gap-analyst.md +22 -0
  271. package/modules/radar/src/core/agents/security-engineer.md +25 -0
  272. package/modules/radar/src/core/agents/senior-app-engineer.md +25 -0
  273. package/modules/radar/src/core/agents/sre.md +25 -0
  274. package/modules/radar/src/core/agents/staff-engineer.md +23 -0
  275. package/modules/radar/src/core/agents/test-engineer.md +25 -0
  276. package/modules/radar/src/core/personas/architect.md +111 -0
  277. package/modules/radar/src/core/personas/compliance-officer.md +104 -0
  278. package/modules/radar/src/core/personas/data-engineer.md +113 -0
  279. package/modules/radar/src/core/personas/devils-advocate.md +105 -0
  280. package/modules/radar/src/core/personas/performance-engineer.md +119 -0
  281. package/modules/radar/src/core/personas/principal-engineer.md +119 -0
  282. package/modules/radar/src/core/personas/reality-gap-analyst.md +111 -0
  283. package/modules/radar/src/core/personas/security-engineer.md +108 -0
  284. package/modules/radar/src/core/personas/senior-app-engineer.md +111 -0
  285. package/modules/radar/src/core/personas/sre.md +117 -0
  286. package/modules/radar/src/core/personas/staff-engineer.md +109 -0
  287. package/modules/radar/src/core/personas/test-engineer.md +109 -0
  288. package/modules/radar/src/core/workflows/disagreement-resolution.md +183 -0
  289. package/modules/radar/src/core/workflows/phase-0-context.md +148 -0
  290. package/modules/radar/src/core/workflows/phase-1-reconnaissance.md +169 -0
  291. package/modules/radar/src/core/workflows/phase-2-domain-audits.md +190 -0
  292. package/modules/radar/src/core/workflows/phase-3-cross-domain.md +177 -0
  293. package/modules/radar/src/core/workflows/phase-4-adversarial-review.md +165 -0
  294. package/modules/radar/src/core/workflows/phase-5-report.md +189 -0
  295. package/modules/radar/src/core/workflows/phase-checkpoint.md +222 -0
  296. package/modules/radar/src/core/workflows/session-handoff.md +152 -0
  297. package/modules/radar/src/domains/00-context.md +201 -0
  298. package/modules/radar/src/domains/01-architecture.md +248 -0
  299. package/modules/radar/src/domains/02-data.md +224 -0
  300. package/modules/radar/src/domains/03-correctness.md +230 -0
  301. package/modules/radar/src/domains/04-security.md +274 -0
  302. package/modules/radar/src/domains/05-compliance.md +228 -0
  303. package/modules/radar/src/domains/06-testing.md +228 -0
  304. package/modules/radar/src/domains/07-reliability.md +246 -0
  305. package/modules/radar/src/domains/08-performance.md +247 -0
  306. package/modules/radar/src/domains/09-maintainability.md +271 -0
  307. package/modules/radar/src/domains/10-operability.md +250 -0
  308. package/modules/radar/src/domains/11-change-risk.md +246 -0
  309. package/modules/radar/src/domains/12-team-risk.md +221 -0
  310. package/modules/radar/src/domains/13-risk-synthesis.md +202 -0
  311. package/modules/radar/src/rules/agent-boundaries.md +78 -0
  312. package/modules/radar/src/rules/disagreement-protocol.md +76 -0
  313. package/modules/radar/src/rules/epistemic-hygiene.md +78 -0
  314. package/modules/radar/src/schemas/confidence.md +185 -0
  315. package/modules/radar/src/schemas/disagreement.md +238 -0
  316. package/modules/radar/src/schemas/finding.md +287 -0
  317. package/modules/radar/src/schemas/report-section.md +150 -0
  318. package/modules/radar/src/schemas/signal.md +108 -0
  319. package/modules/radar/src/tools/checkov.md +463 -0
  320. package/modules/radar/src/tools/git-history.md +581 -0
  321. package/modules/radar/src/tools/gitleaks.md +447 -0
  322. package/modules/radar/src/tools/grype.md +611 -0
  323. package/modules/radar/src/tools/semgrep.md +378 -0
  324. package/modules/radar/src/tools/sonarqube.md +550 -0
  325. package/modules/radar/src/tools/syft.md +539 -0
  326. package/modules/radar/src/tools/trivy.md +439 -0
  327. package/modules/radar/src/transform/agents/change-risk-modeler.md +24 -0
  328. package/modules/radar/src/transform/agents/execution-validator.md +24 -0
  329. package/modules/radar/src/transform/agents/guardrail-generator.md +24 -0
  330. package/modules/radar/src/transform/agents/pedagogy-agent.md +24 -0
  331. package/modules/radar/src/transform/agents/remediation-architect.md +24 -0
  332. package/modules/radar/src/transform/personas/change-risk-modeler.md +95 -0
  333. package/modules/radar/src/transform/personas/execution-validator.md +95 -0
  334. package/modules/radar/src/transform/personas/guardrail-generator.md +103 -0
  335. package/modules/radar/src/transform/personas/pedagogy-agent.md +105 -0
  336. package/modules/radar/src/transform/personas/remediation-architect.md +95 -0
  337. package/modules/radar/src/transform/rules/change-risk-rules.md +87 -0
  338. package/modules/radar/src/transform/rules/safety-governance.md +87 -0
  339. package/modules/radar/src/transform/schemas/change-risk.md +139 -0
  340. package/modules/radar/src/transform/schemas/intervention-level.md +207 -0
  341. package/modules/radar/src/transform/schemas/playbook.md +205 -0
  342. package/modules/radar/src/transform/schemas/verification-plan.md +134 -0
  343. package/modules/radar/src/transform/workflows/phase-6-remediation.md +148 -0
  344. package/modules/radar/src/transform/workflows/phase-7-risk-validation.md +161 -0
  345. package/modules/radar/src/transform/workflows/phase-8-execution-planning.md +159 -0
  346. package/modules/radar/src/transform/workflows/transform-safety.md +158 -0
  347. package/modules/vector/.vector-template/sessions/.gitkeep +0 -0
  348. package/modules/vector/.vector-template/vector.json +72 -0
  349. package/modules/vector/AUDIT-CLAUDEMD.md +154 -0
  350. package/modules/vector/INSTALL.md +185 -0
  351. package/modules/vector/LICENSE +21 -0
  352. package/modules/vector/README.md +409 -0
  353. package/modules/vector/VECTOR-BLOCK.md +57 -0
  354. package/modules/vector/assets/terminal.svg +68 -0
  355. package/modules/vector/bin/install.js +455 -0
  356. package/modules/vector/bin/migrate-v1-to-v2.sh +492 -0
  357. package/modules/vector/commands/help.md +46 -0
  358. package/modules/vector/hooks/vector-hook.py +775 -0
  359. package/modules/vector/mcp/index.js +118 -0
  360. package/modules/vector/mcp/package.json +10 -0
  361. package/modules/vector/mcp/tools/decisions.js +269 -0
  362. package/modules/vector/mcp/tools/domains.js +361 -0
  363. package/modules/vector/mcp/tools/staging.js +252 -0
  364. package/modules/vector/mcp/tools/vector-json.js +647 -0
  365. package/modules/vector/package.json +38 -0
  366. package/modules/vector/schemas/vector.schema.json +237 -0
  367. package/package.json +39 -0
  368. package/shared/branding/branding.js +70 -0
  369. package/shared/config/defaults.json +59 -0
  370. package/shared/events/README.md +175 -0
  371. package/shared/events/event-bus.js +134 -0
  372. package/shared/events/event_bus.py +255 -0
  373. package/shared/events/integrations.js +161 -0
  374. package/shared/events/schemas/audit-complete.schema.json +21 -0
  375. package/shared/events/schemas/phase-progress.schema.json +23 -0
  376. package/shared/events/schemas/plan-created.schema.json +21 -0
@@ -0,0 +1,775 @@
1
+ #!/usr/bin/env python3
2
+ # VECTOR_HOOK_VERSION=2.0.0
3
+ """
4
+ Vector - Context Augmentation & Reinforcement Layer
5
+ Smart Injector Hook (v2 — JSON-based)
6
+
7
+ Reads from .vector/vector.json instead of manifest + domain files.
8
+ All other behavior identical to v1 (vector-hook-v1.py).
9
+
10
+ Drop-in replacement: swap hook path in settings.json when ready.
11
+ Legacy vector-hook-v1.py reads manifest + domain files (unchanged).
12
+
13
+ What gets injected:
14
+ 1. Context bracket rules (FRESH/MODERATE/DEPLETED) — from vector.json config
15
+ 2. GLOBAL domain rules (always_on)
16
+ 3. Matched domain rules (keyword matching)
17
+ 4. Domain decisions (per-domain)
18
+ 5. Star commands — from vector.json config
19
+ """
20
+ import json
21
+ import sys
22
+ import re
23
+ from pathlib import Path
24
+ from datetime import datetime, timedelta
25
+ from typing import Optional
26
+
27
+
28
+ VECTOR_FOLDER = '.vector'
29
+ VECTOR_JSON = 'vector.json'
30
+ SESSIONS_FOLDER = 'sessions'
31
+ MAX_CONTEXT = 1000000
32
+ STALE_SESSION_HOURS = 24
33
+ DEBUG = False
34
+
35
+ ENABLE_CONTEXT_DEDUP = True
36
+ FORCE_EMIT_EVERY_N = 5
37
+
38
+
39
+ def debug_log(msg: str):
40
+ if DEBUG:
41
+ print(f"[Vector-v2] {msg}", file=sys.stderr)
42
+
43
+
44
+ def compute_context_signature(
45
+ bracket: str,
46
+ devmode: bool,
47
+ always_on_domains: list,
48
+ matched_domains: list,
49
+ command_names: list
50
+ ) -> str:
51
+ parts = [
52
+ "b:{}".format(bracket),
53
+ "d:{}".format(devmode),
54
+ "a:{}".format(','.join(sorted(always_on_domains))),
55
+ "m:{}".format(','.join(sorted(matched_domains))),
56
+ "c:{}".format(','.join(sorted(command_names)))
57
+ ]
58
+ return "|".join(parts)
59
+
60
+
61
+ # =============================================================================
62
+ # SESSION MANAGEMENT
63
+ # =============================================================================
64
+
65
+ def get_sessions_path(vector_path: Path) -> Path:
66
+ sessions_path = vector_path / SESSIONS_FOLDER
67
+ sessions_path.mkdir(parents=True, exist_ok=True)
68
+ return sessions_path
69
+
70
+
71
+ def load_session_config(vector_path: Path, session_id: str) -> Optional[dict]:
72
+ if not session_id:
73
+ return None
74
+ sessions_path = get_sessions_path(vector_path)
75
+ session_file = sessions_path / f"{session_id}.json"
76
+ if not session_file.exists():
77
+ return None
78
+ try:
79
+ with open(session_file, 'r') as f:
80
+ return json.load(f)
81
+ except (json.JSONDecodeError, IOError):
82
+ return None
83
+
84
+
85
+ def save_session_config(vector_path: Path, session_config: dict) -> bool:
86
+ session_id = session_config.get('uuid')
87
+ if not session_id:
88
+ return False
89
+ sessions_path = get_sessions_path(vector_path)
90
+ session_file = sessions_path / f"{session_id}.json"
91
+ try:
92
+ with open(session_file, 'w') as f:
93
+ json.dump(session_config, f, indent=2)
94
+ return True
95
+ except IOError:
96
+ return False
97
+
98
+
99
+ def create_session_config(session_id: str, cwd: str, vector_data: dict) -> dict:
100
+ now = datetime.now().isoformat()
101
+ label = Path(cwd).name or "unknown"
102
+ overrides = {"DEVMODE": None}
103
+ for domain_name in vector_data.get('domains', {}).keys():
104
+ overrides[f"{domain_name}_STATE"] = None
105
+ return {
106
+ "uuid": session_id,
107
+ "started": now,
108
+ "cwd": cwd,
109
+ "label": label,
110
+ "title": None,
111
+ "prompt_count": 0,
112
+ "last_activity": now,
113
+ "overrides": overrides,
114
+ "last_context_signature": None
115
+ }
116
+
117
+
118
+ def update_session_activity(vector_path: Path, session_id: str) -> None:
119
+ session_config = load_session_config(vector_path, session_id)
120
+ if session_config:
121
+ session_config['last_activity'] = datetime.now().isoformat()
122
+ save_session_config(vector_path, session_config)
123
+
124
+
125
+ def cleanup_stale_sessions(vector_path: Path) -> list:
126
+ cleaned = []
127
+ sessions_path = get_sessions_path(vector_path)
128
+ threshold = datetime.now() - timedelta(hours=STALE_SESSION_HOURS)
129
+ for session_file in sessions_path.glob("*.json"):
130
+ try:
131
+ with open(session_file, 'r') as f:
132
+ config = json.load(f)
133
+ last_activity = config.get('last_activity', config.get('started', ''))
134
+ if last_activity:
135
+ last_dt = datetime.fromisoformat(last_activity)
136
+ if last_dt < threshold:
137
+ session_file.unlink()
138
+ cleaned.append(config.get('uuid', session_file.stem))
139
+ except Exception:
140
+ pass
141
+ return cleaned
142
+
143
+
144
+ def merge_config_with_session(
145
+ domains: dict,
146
+ global_exclude: list,
147
+ devmode: bool,
148
+ session_config: Optional[dict]
149
+ ) -> tuple:
150
+ if not session_config:
151
+ return domains, global_exclude, devmode
152
+ overrides = session_config.get('overrides', {})
153
+ if overrides.get('DEVMODE') is not None:
154
+ devmode = overrides['DEVMODE']
155
+ for domain_name in list(domains.keys()):
156
+ key = f"{domain_name}_STATE"
157
+ if overrides.get(key) is not None:
158
+ domains[domain_name]['state'] = overrides[key]
159
+ return domains, global_exclude, devmode
160
+
161
+
162
+ def get_or_create_session(vector_path: Path, session_id: str, cwd: str, vector_data: dict) -> Optional[dict]:
163
+ if not session_id:
164
+ return None
165
+ session_config = load_session_config(vector_path, session_id)
166
+ if session_config is None:
167
+ session_config = create_session_config(session_id, cwd, vector_data)
168
+ cleanup_stale_sessions(vector_path)
169
+ session_config['prompt_count'] = session_config.get('prompt_count', 0) + 1
170
+ session_config['last_activity'] = datetime.now().isoformat()
171
+ save_session_config(vector_path, session_config)
172
+ return session_config
173
+
174
+
175
+ # =============================================================================
176
+ # CONTEXT PERCENTAGE & BRACKETS
177
+ # =============================================================================
178
+
179
+ def get_context_percentage(input_data: dict) -> Optional[float]:
180
+ try:
181
+ tokens_remaining = input_data.get('context', {}).get('tokensRemaining')
182
+ tokens_used = input_data.get('context', {}).get('tokensUsed')
183
+ if tokens_remaining is not None and tokens_used is not None:
184
+ total = tokens_remaining + tokens_used
185
+ if total > 0:
186
+ return (tokens_remaining / total) * 100
187
+ turn = input_data.get('context', {}).get('conversationTurnNumber', 1)
188
+ if turn and turn > 1:
189
+ estimated_used = turn * 3000
190
+ remaining = MAX_CONTEXT - estimated_used
191
+ if remaining > 0:
192
+ return (remaining / MAX_CONTEXT) * 100
193
+ except Exception:
194
+ pass
195
+ return None
196
+
197
+
198
+ def get_active_bracket(context_remaining: Optional[float]) -> str:
199
+ if context_remaining is None:
200
+ return "FRESH"
201
+ if context_remaining >= 70:
202
+ return "FRESH"
203
+ elif context_remaining >= 40:
204
+ return "MODERATE"
205
+ elif context_remaining >= 15:
206
+ return "DEPLETED"
207
+ else:
208
+ return "CRITICAL"
209
+
210
+
211
+ # =============================================================================
212
+ # V2: JSON-BASED DATA LOADING
213
+ # =============================================================================
214
+
215
+ def find_all_vector_scopes(cwd: str) -> list:
216
+ """Find all .vector/ directories with vector.json by walking up directory tree."""
217
+ scopes = []
218
+ search_path = Path(cwd)
219
+ for i in range(10):
220
+ candidate = search_path / VECTOR_FOLDER
221
+ vector_json_path = candidate / VECTOR_JSON
222
+ if candidate.exists() and vector_json_path.exists():
223
+ label = "project" if i == 0 else "scope-{}".format(search_path.name)
224
+ scopes.append((candidate, label))
225
+ debug_log("Found .vector/ scope at {} ({})".format(candidate, label))
226
+ if search_path.parent == search_path:
227
+ break
228
+ search_path = search_path.parent
229
+ return scopes
230
+
231
+
232
+ def load_vector_json(vector_path: Path) -> Optional[dict]:
233
+ """Load vector.json from a .vector/ directory. Returns None if not found."""
234
+ vector_json_path = vector_path / VECTOR_JSON
235
+ if not vector_json_path.exists():
236
+ return None
237
+ try:
238
+ with open(vector_json_path, 'r') as f:
239
+ return json.load(f)
240
+ except (json.JSONDecodeError, IOError):
241
+ return None
242
+
243
+
244
+ def vector_json_to_domains(vector_data: dict) -> dict:
245
+ """
246
+ Convert vector.json domains to the internal domains dict format
247
+ that match_domains_to_prompt() expects.
248
+ """
249
+ domains = {}
250
+ for name, domain_data in vector_data.get('domains', {}).items():
251
+ state_str = domain_data.get('state', 'inactive')
252
+ domains[name] = {
253
+ 'state': state_str in ('active', True, 'true'),
254
+ 'always_on': domain_data.get('always_on', False),
255
+ 'recall': ', '.join(domain_data.get('recall', [])),
256
+ 'recall_list': [kw.lower() for kw in domain_data.get('recall', [])],
257
+ 'exclude_list': [kw.lower() for kw in domain_data.get('exclude', [])],
258
+ }
259
+ return domains
260
+
261
+
262
+ def get_domain_rules_from_json(vector_data: dict, domain_name: str) -> list:
263
+ """Extract rule texts from vector.json for a given domain."""
264
+ domain = vector_data.get('domains', {}).get(domain_name, {})
265
+ return [r.get('text', '') for r in domain.get('rules', []) if r.get('text')]
266
+
267
+
268
+ def get_domain_decisions_from_json(vector_data: dict, domain_name: str) -> list:
269
+ """Extract decisions from vector.json for a given domain."""
270
+ domain = vector_data.get('domains', {}).get(domain_name, {})
271
+ return [d for d in domain.get('decisions', []) if d.get('status', 'active') == 'active']
272
+
273
+
274
+ def get_all_decisions_summary(vector_data: dict) -> str:
275
+ """
276
+ Generate standalone <decisions> summary across ALL domains.
277
+ Replaces the former get-decisions-summary.py hook.
278
+ """
279
+ if not vector_data:
280
+ return ''
281
+
282
+ domain_summaries = []
283
+ total_active = 0
284
+ total_archived = 0
285
+
286
+ for dname, ddata in vector_data.get('domains', {}).items():
287
+ decisions = ddata.get('decisions', [])
288
+ active = len([d for d in decisions if d.get('status', 'active') == 'active'])
289
+ archived = len([d for d in decisions if d.get('status') == 'archived'])
290
+ if active > 0:
291
+ domain_summaries.append(f"{dname.lower()} ({active})")
292
+ total_active += active
293
+ total_archived += archived
294
+
295
+ if not domain_summaries and total_active == 0:
296
+ return '<decisions>No decisions logged yet. Use vector_log_decision tool to start.</decisions>'
297
+
298
+ lines = [
299
+ '<decisions>',
300
+ 'Domains: {}'.format(', '.join(domain_summaries)),
301
+ 'Total: {} active, {} archived'.format(total_active, total_archived),
302
+ 'Tools: vector_search_decisions(keyword), vector_get_decisions(domain), vector_log_decision(domain, decision, rationale, recall)',
303
+ '</decisions>',
304
+ ]
305
+ return '\n'.join(lines)
306
+
307
+
308
+ def merge_vector_scopes(scopes: list) -> tuple:
309
+ """
310
+ Merge multiple .vector/ scopes from vector.json files.
311
+ Returns (vector_data, vector_path, domains, global_exclude, devmode)
312
+ All data comes from vector.json — no flat file fallbacks.
313
+ """
314
+ if not scopes:
315
+ return None, None, {}, [], False
316
+
317
+ merged_vector_data = {"config": {}, "domains": {}, "staging": []}
318
+ merged_global_exclude = []
319
+ merged_devmode = False
320
+ merged_context_brackets = {}
321
+ merged_commands = {}
322
+
323
+ for vector_path, _ in reversed(scopes):
324
+ vector_data = load_vector_json(vector_path)
325
+ if vector_data:
326
+ config = vector_data.get('config', {})
327
+ if config.get('devmode') is not None:
328
+ merged_devmode = config['devmode']
329
+ if config.get('global_exclude'):
330
+ merged_global_exclude = config['global_exclude']
331
+
332
+ # Merge context brackets (more-specific overrides)
333
+ for bracket_name, bracket_config in config.get('context_brackets', {}).items():
334
+ merged_context_brackets[bracket_name] = bracket_config
335
+
336
+ # Merge star commands (more-specific overrides)
337
+ for cmd_name, cmd_rules in config.get('commands', {}).items():
338
+ merged_commands[cmd_name] = cmd_rules
339
+
340
+ for dname, dconfig in vector_data.get('domains', {}).items():
341
+ merged_vector_data['domains'][dname] = dconfig
342
+
343
+ merged_vector_data['staging'].extend(vector_data.get('staging', []))
344
+
345
+ merged_vector_data['config'] = {
346
+ 'devmode': merged_devmode,
347
+ 'post_compact_gate': True,
348
+ 'global_exclude': merged_global_exclude,
349
+ 'context_brackets': merged_context_brackets,
350
+ 'commands': merged_commands
351
+ }
352
+
353
+ merged_domains = vector_json_to_domains(merged_vector_data)
354
+
355
+ primary_vector_path = scopes[0][0]
356
+ return merged_vector_data, primary_vector_path, merged_domains, merged_global_exclude, merged_devmode
357
+
358
+
359
+ # =============================================================================
360
+ # STAR COMMANDS (detection only — rules come from vector.json)
361
+ # =============================================================================
362
+
363
+ def detect_star_commands(user_prompt: str) -> list:
364
+ matches = re.findall(r'\*(\w+)', user_prompt)
365
+ return [m.upper() for m in matches] if matches else []
366
+
367
+
368
+ # =============================================================================
369
+ # MATCHING & EXCLUSIONS
370
+ # =============================================================================
371
+
372
+ def check_exclusions(prompt_lower: str, exclude_list: list) -> list:
373
+ matched_exclusions = []
374
+ for keyword in exclude_list:
375
+ pattern = re.escape(keyword)
376
+ if re.search(pattern, prompt_lower):
377
+ matched_exclusions.append(keyword)
378
+ return matched_exclusions
379
+
380
+
381
+ def match_domains_to_prompt(
382
+ domains: dict,
383
+ user_prompt: str,
384
+ global_exclude: list
385
+ ) -> tuple:
386
+ matched = {}
387
+ excluded = {}
388
+ prompt_lower = user_prompt.lower()
389
+ global_excluded = check_exclusions(prompt_lower, global_exclude)
390
+ if global_excluded:
391
+ return matched, excluded, global_excluded
392
+ for domain, config in domains.items():
393
+ if not config.get('state', False) or config.get('always_on', False):
394
+ continue
395
+ recall_list = config.get('recall_list', [])
396
+ if not recall_list:
397
+ continue
398
+ exclude_list = config.get('exclude_list', [])
399
+ if exclude_list:
400
+ domain_exclusions = check_exclusions(prompt_lower, exclude_list)
401
+ if domain_exclusions:
402
+ excluded[domain] = domain_exclusions
403
+ continue
404
+ domain_matches = []
405
+ for keyword in recall_list:
406
+ pattern = re.escape(keyword)
407
+ if re.search(pattern, prompt_lower):
408
+ domain_matches.append(keyword)
409
+ if domain_matches:
410
+ matched[domain] = domain_matches
411
+ return matched, excluded, global_excluded
412
+
413
+
414
+ # =============================================================================
415
+ # OUTPUT FORMATTING
416
+ # =============================================================================
417
+
418
+ def format_output(
419
+ domains: dict,
420
+ always_on_rules: dict,
421
+ matched_rules: dict,
422
+ matched_keywords: dict,
423
+ excluded_domains: dict,
424
+ global_excluded: list,
425
+ devmode: bool,
426
+ bracket: str = "FRESH",
427
+ context_remaining: Optional[float] = None,
428
+ bracket_rules: Optional[list] = None,
429
+ command_rules: Optional[dict] = None,
430
+ global_disabled: bool = False,
431
+ domains_with_rules: Optional[set] = None,
432
+ context_enabled: bool = True,
433
+ domain_decisions: Optional[dict] = None
434
+ ) -> str:
435
+ output = "\n<vector-rules>\n"
436
+
437
+ if context_enabled:
438
+ if context_remaining is not None:
439
+ is_critical = bracket == "CRITICAL"
440
+ if is_critical:
441
+ output += f"⚠️ CONTEXT CRITICAL: {context_remaining:.0f}% remaining ⚠️\n"
442
+ output += "Recommend: compact session OR spawn fresh agent for remaining work\n\n"
443
+ output += f"CONTEXT BRACKET: [{bracket}] ({context_remaining:.0f}% remaining)\n"
444
+ else:
445
+ output += f"CONTEXT BRACKET: [{bracket}] (fresh session)\n"
446
+ if bracket_rules:
447
+ output += f"\n[{bracket}] CONTEXT RULES:\n"
448
+ for i, rule in enumerate(bracket_rules, 1):
449
+ output += f" {i}. {rule}\n"
450
+ output += "\n"
451
+
452
+ if command_rules:
453
+ output += "🎯 ACTIVE COMMANDS 🎯\n"
454
+ output += "="*60 + "\n"
455
+ output += "EXPLICIT COMMAND INVOCATION - EXECUTE THESE INSTRUCTIONS:\n\n"
456
+ for cmd, rules in command_rules.items():
457
+ output += f"[*{cmd.lower()}] COMMAND:\n"
458
+ for i, rule in enumerate(rules):
459
+ output += f" {i}. {rule}\n"
460
+ output += "\n"
461
+ output += "="*60 + "\n\n"
462
+
463
+ if devmode:
464
+ output += "⚠️ DEVMODE=true ⚠️\n"
465
+ output += "="*60 + "\n"
466
+ output += "MANDATORY: Append a DEVMODE block at the end of EVERY response.\n"
467
+ output += "NEVER skip it. NEVER forget it. NEVER omit it for any reason.\n"
468
+ output += "NEVER fabricate data in the block — only report what you actually received.\n"
469
+ output += "NEVER invent rule numbers, citation counts, or applied counts.\n"
470
+ output += "NEVER write a DEVMODE block from memory — always derive it from THIS prompt's context.\n\n"
471
+ output += "This is a signal dashboard the user reads to tune their context systems.\n\n"
472
+ output += "How to fill each field:\n"
473
+ output += "- Vector: If you received <vector-rules> THIS prompt → list domain names + rule count from the injection.\n"
474
+ output += " If you received <vector-status dedup=\"true\"> → write 'dedup (prompt N)' using the prompt number from the tag.\n"
475
+ output += "- Rules: Total = count of rules in the last <vector-rules> injection. applied = how many you consciously followed in THIS response. 0 is fine and expected.\n"
476
+ output += "- Decisions: Total = count from <decisions> tag. applied = how many influenced THIS response. Usually 0.\n"
477
+ output += "- Signals: List every hook tag you received THIS prompt (e.g. pulse, active, backlog, calendar, time, machine, context, vector-rules, vector-status, decisions, psmm). Only list tags actually present.\n"
478
+ output += "- Applied: Which of those signals actually shaped your response content. 'none' is the honest default.\n"
479
+ output += "- Tools: Which Claude Code tools you called in THIS response. 'none' if you made no tool calls.\n"
480
+ output += "- Gaps: If you noticed missing context or something that should have been injected but wasn't. Usually 'none'.\n\n"
481
+ output += "Format EXACTLY (keep under 8 lines, no rationale, no prose):\n"
482
+ output += "---\n```\n"
483
+ output += "🔧 Vector DEVMODE\n"
484
+ output += "Vector: [see rules above]\n"
485
+ output += "Rules: [total] | applied: [count, or 0]\n"
486
+ output += "Decisions: [total] | applied: [count, or 0]\n"
487
+ output += "Signals: [tags received this prompt]\n"
488
+ output += "Applied: [which signals shaped response, or 'none']\n"
489
+ output += "Tools: [tools used, or 'none']\n"
490
+ output += "Gaps: [one-line, or 'none']\n"
491
+ output += "```\n---\n"
492
+ output += "="*60 + "\n\n"
493
+ else:
494
+ output += "🚫 DEVMODE=false 🚫\n"
495
+ output += "User has DISABLED debug output. Do NOT append any Vector DEVMODE\n"
496
+ output += "debug section to your responses. Respond normally without debug blocks.\n\n"
497
+
498
+ if global_disabled:
499
+ output += "⛔ GLOBAL RULES DISABLED ⛔\n"
500
+ output += "="*60 + "\n"
501
+ output += "CRITICAL: User has INTENTIONALLY disabled GLOBAL domain rules.\n"
502
+ output += "Do NOT apply any previously-seen GLOBAL rules from conversation memory.\n"
503
+ output += "This is an explicit override - await future activation to resume.\n"
504
+ output += "="*60 + "\n\n"
505
+
506
+ output += "LOADED DOMAINS:\n"
507
+ for domain in always_on_rules:
508
+ output += f" [{domain}] always_on ({len(always_on_rules[domain])} rules)\n"
509
+ for domain in matched_rules:
510
+ keywords = matched_keywords.get(domain, [])
511
+ output += f" [{domain}] matched: {', '.join(keywords)} ({len(matched_rules[domain])} rules)\n"
512
+ if not always_on_rules and not matched_rules:
513
+ output += " (none)\n"
514
+
515
+ if global_excluded:
516
+ output += f"\nGLOBAL EXCLUSION ACTIVE: {', '.join(global_excluded)}\n"
517
+ output += " (All domain matching skipped)\n"
518
+ if excluded_domains:
519
+ output += "\nEXCLUDED DOMAINS:\n"
520
+ for domain, exclusions in excluded_domains.items():
521
+ output += f" [{domain}] excluded by: {', '.join(exclusions)}\n"
522
+
523
+ for domain, rules in always_on_rules.items():
524
+ output += f"\n[{domain}] RULES:\n"
525
+ for i, rule in enumerate(rules):
526
+ output += f" {i}. {rule}\n"
527
+ if domain_decisions and domain in domain_decisions:
528
+ decisions = domain_decisions[domain]
529
+ output += f"\n[{domain}] DECISIONS ({len(decisions)}):\n"
530
+ for d in decisions:
531
+ output += " - {} ({}): {}\n".format(
532
+ d.get('decision', ''), d.get('date', ''), d.get('rationale', ''))
533
+
534
+ for domain, rules in matched_rules.items():
535
+ output += f"\n[{domain}] RULES:\n"
536
+ for i, rule in enumerate(rules):
537
+ output += f" {i}. {rule}\n"
538
+ if domain_decisions and domain in domain_decisions:
539
+ decisions = domain_decisions[domain]
540
+ output += f"\n[{domain}] DECISIONS ({len(decisions)}):\n"
541
+ for d in decisions:
542
+ output += " - {} ({}): {}\n".format(
543
+ d.get('decision', ''), d.get('date', ''), d.get('rationale', ''))
544
+
545
+ unloaded = []
546
+ for domain, config in domains.items():
547
+ if config.get('state', False) and not config.get('always_on', False):
548
+ if domain not in matched_rules and domain not in excluded_domains:
549
+ if domains_with_rules is None or domain in domains_with_rules:
550
+ recall = config.get('recall', '')
551
+ unloaded.append(f"{domain} ({recall})")
552
+ if unloaded:
553
+ output += "\nAVAILABLE (not loaded):\n"
554
+ for item in unloaded:
555
+ output += f" {item}\n"
556
+ output += "Use drl_get_domain_rules(domain) to load manually if needed.\n"
557
+
558
+ output += "</vector-rules>\n"
559
+ return output
560
+
561
+
562
+ # =============================================================================
563
+ # MAIN (v2 — reads vector.json instead of manifest + domain files)
564
+ # =============================================================================
565
+
566
+ def main():
567
+ try:
568
+ input_data = json.load(sys.stdin)
569
+ except json.JSONDecodeError as e:
570
+ print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
571
+ sys.exit(1)
572
+
573
+ cwd = input_data.get('cwd', str(Path.home()))
574
+ session_id = input_data.get('sessionId', '') or input_data.get('session_id', '')
575
+ user_prompt = (
576
+ input_data.get('prompt', '') or
577
+ input_data.get('userInput', '') or
578
+ input_data.get('message', '') or
579
+ input_data.get('input', '')
580
+ )
581
+
582
+ # Find all .vector/ scopes
583
+ scopes = find_all_vector_scopes(cwd)
584
+ if not scopes:
585
+ sys.exit(0)
586
+
587
+ # Merge scopes — vector.json based (all data from JSON, no flat files)
588
+ vector_data, vector_path, domains, global_exclude, devmode = merge_vector_scopes(scopes)
589
+
590
+ if not domains or vector_path is None:
591
+ sys.exit(0)
592
+
593
+ # Session management
594
+ session_config = get_or_create_session(vector_path, session_id, cwd, vector_data or {})
595
+
596
+ # Merge with session overrides
597
+ domains, global_exclude, devmode = merge_config_with_session(
598
+ domains, global_exclude, devmode, session_config
599
+ )
600
+
601
+ # Context percentage and bracket
602
+ context_remaining = get_context_percentage(input_data)
603
+ bracket = get_active_bracket(context_remaining)
604
+
605
+ # Context bracket rules from vector.json config
606
+ bracket_rules_list = []
607
+ context_enabled = True
608
+ if session_config:
609
+ overrides = session_config.get('overrides', {})
610
+ if overrides.get('CONTEXT_STATE') is not None:
611
+ context_enabled = overrides['CONTEXT_STATE']
612
+ if vector_data and context_enabled:
613
+ context_brackets = vector_data.get('config', {}).get('context_brackets', {})
614
+ rules_bracket = "DEPLETED" if bracket == "CRITICAL" else bracket
615
+ bracket_config = context_brackets.get(rules_bracket, {})
616
+ if bracket_config.get('enabled', True):
617
+ bracket_rules_list = bracket_config.get('rules', [])
618
+
619
+ # GLOBAL disabled check
620
+ global_disabled = False
621
+ if 'GLOBAL' in domains:
622
+ if not domains['GLOBAL'].get('state', True):
623
+ global_disabled = True
624
+
625
+ # Load ALWAYS_ON domain rules from vector.json
626
+ always_on_rules = {}
627
+ if vector_data:
628
+ for domain, config in domains.items():
629
+ is_always_on = config.get('always_on', False) or domain == 'GLOBAL'
630
+ if is_always_on and config.get('state', True):
631
+ rules = get_domain_rules_from_json(vector_data, domain)
632
+ if rules:
633
+ always_on_rules[domain] = rules
634
+
635
+ # Star commands from vector.json config
636
+ command_rules = {}
637
+ if user_prompt and vector_data:
638
+ all_commands = vector_data.get('config', {}).get('commands', {})
639
+ if all_commands:
640
+ star_commands = detect_star_commands(user_prompt)
641
+ for cmd in star_commands:
642
+ if cmd in all_commands:
643
+ command_rules[cmd] = all_commands[cmd]
644
+
645
+ # Match domains to prompt
646
+ matched_keywords = {}
647
+ matched_rules = {}
648
+ excluded_domains = {}
649
+ global_excluded = []
650
+
651
+ if user_prompt:
652
+ matched_keywords, excluded_domains, global_excluded = match_domains_to_prompt(
653
+ domains, user_prompt, global_exclude
654
+ )
655
+ if vector_data:
656
+ for domain in matched_keywords:
657
+ if domain == 'COMMANDS':
658
+ continue
659
+ rules = get_domain_rules_from_json(vector_data, domain)
660
+ if rules:
661
+ matched_rules[domain] = rules
662
+
663
+ matched_keywords.pop('COMMANDS', None)
664
+
665
+ # Load decisions from vector.json
666
+ domain_decisions = {}
667
+ if vector_data:
668
+ for domain in list(always_on_rules.keys()) + list(matched_rules.keys()):
669
+ decisions = get_domain_decisions_from_json(vector_data, domain)
670
+ if decisions:
671
+ domain_decisions[domain] = decisions
672
+
673
+ # Build set of domains that have rules (for AVAILABLE listing)
674
+ domains_with_rules = set()
675
+ if vector_data:
676
+ for dname, ddata in vector_data.get('domains', {}).items():
677
+ if ddata.get('rules'):
678
+ domains_with_rules.add(dname)
679
+
680
+ # Context deduplication
681
+ current_signature = compute_context_signature(
682
+ bracket, devmode,
683
+ list(always_on_rules.keys()),
684
+ list(matched_rules.keys()),
685
+ list(command_rules.keys())
686
+ )
687
+
688
+ prompt_count = session_config.get('prompt_count', 1) if session_config else 1
689
+ last_signature = session_config.get('last_context_signature') if session_config else None
690
+
691
+ should_emit_full = True
692
+ if ENABLE_CONTEXT_DEDUP and session_config:
693
+ signature_changed = (current_signature != last_signature)
694
+ force_emit = (prompt_count % FORCE_EMIT_EVERY_N == 0)
695
+ first_prompt = (prompt_count <= 1)
696
+ if not signature_changed and not force_emit and not first_prompt:
697
+ should_emit_full = False
698
+ else:
699
+ session_config['last_context_signature'] = current_signature
700
+ save_session_config(vector_path, session_config)
701
+
702
+ # Generate decisions summary (always, regardless of dedup)
703
+ decisions_summary = get_all_decisions_summary(vector_data) if vector_data else ''
704
+
705
+ if should_emit_full:
706
+ context = format_output(
707
+ domains,
708
+ always_on_rules,
709
+ matched_rules,
710
+ matched_keywords,
711
+ excluded_domains,
712
+ global_excluded,
713
+ devmode,
714
+ bracket,
715
+ context_remaining,
716
+ bracket_rules_list,
717
+ command_rules,
718
+ global_disabled,
719
+ domains_with_rules,
720
+ context_enabled,
721
+ domain_decisions
722
+ )
723
+
724
+ if decisions_summary:
725
+ context += "\n" + decisions_summary + "\n"
726
+
727
+ output = {
728
+ "hookSpecificOutput": {
729
+ "hookEventName": "UserPromptSubmit",
730
+ "additionalContext": context
731
+ }
732
+ }
733
+ print(json.dumps(output))
734
+ else:
735
+ loaded = list(always_on_rules.keys()) + list(matched_rules.keys())
736
+ status = "<vector-status dedup=\"true\" prompt=\"{}\" domains=\"{}\">\n".format(
737
+ prompt_count, ','.join(loaded) if loaded else 'GLOBAL'
738
+ )
739
+ status += "Vector rules were NOT injected this prompt (dedup: signature unchanged).\n"
740
+ status += "Prior injection is still in your context window — operate on those rules.\n"
741
+
742
+ if devmode:
743
+ status += "\n"
744
+ status += "DEVMODE=true — MANDATORY DEVMODE BLOCK REQUIRED.\n"
745
+ status += "NEVER skip the DEVMODE block. NEVER fabricate data in it. NEVER write it from memory.\n"
746
+ status += "Derive every field from THIS prompt's context tags.\n"
747
+ status += "Vector line: 'dedup (prompt {})'\n".format(prompt_count)
748
+ status += "Rules: total from last full injection | applied: count that shaped THIS response (0 is fine)\n"
749
+ status += "Decisions: total from <decisions> tag | applied: count (usually 0)\n"
750
+ status += "Signals: list every hook tag received THIS prompt\n"
751
+ status += "Applied: which signals shaped response, or 'none'\n"
752
+ status += "Tools: tools called THIS response, or 'none'\n"
753
+ status += "Gaps: missing context, or 'none'\n"
754
+ status += "Format: ```🔧 Vector DEVMODE``` block, under 8 lines, at END of EVERY response.\n"
755
+ else:
756
+ status += "DEVMODE=false — do NOT append any debug block.\n"
757
+
758
+ status += "</vector-status>\n"
759
+
760
+ if decisions_summary:
761
+ status += "\n" + decisions_summary + "\n"
762
+
763
+ output = {
764
+ "hookSpecificOutput": {
765
+ "hookEventName": "UserPromptSubmit",
766
+ "additionalContext": status
767
+ }
768
+ }
769
+ print(json.dumps(output))
770
+
771
+ sys.exit(0)
772
+
773
+
774
+ if __name__ == "__main__":
775
+ main()