sinapse-ai 1.7.0 → 1.9.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 (368) hide show
  1. package/.claude/CLAUDE.md +5 -11
  2. package/.claude/hooks/README.md +14 -1
  3. package/.claude/hooks/code-intel-pretool.cjs +115 -0
  4. package/.claude/hooks/enforce-delegation.cjs +31 -3
  5. package/.claude/hooks/enforce-framework-boundary.cjs +324 -0
  6. package/.claude/hooks/enforce-permission-mode.cjs +249 -0
  7. package/.claude/hooks/mind-clone-governance.py +212 -212
  8. package/.claude/hooks/read-protection.py +152 -152
  9. package/.claude/hooks/secret-scanning.cjs +34 -43
  10. package/.claude/hooks/slug-validation.py +175 -175
  11. package/.claude/hooks/sql-governance.py +183 -183
  12. package/.claude/hooks/synapse-engine.cjs +23 -23
  13. package/.claude/hooks/telemetry-post-tool.cjs +128 -0
  14. package/.claude/hooks/telemetry-stop.cjs +132 -0
  15. package/.claude/hooks/verify-packages.cjs +9 -2
  16. package/.claude/rules/documentation-first.md +1 -1
  17. package/.claude/rules/hook-governance.md +3 -1
  18. package/.claude/rules/project-intelligence.md +1 -1
  19. package/.codex/agents/analyst.md +4 -371
  20. package/.codex/agents/animations-orqx.md +4 -57
  21. package/.codex/agents/architect.md +4 -560
  22. package/.codex/agents/brand-orqx.md +4 -95
  23. package/.codex/agents/claude-mastery-chief.md +4 -0
  24. package/.codex/agents/cloning-orqx.md +4 -70
  25. package/.codex/agents/commercial-orqx.md +4 -67
  26. package/.codex/agents/config-engineer.md +2 -2
  27. package/.codex/agents/content-orqx.md +4 -77
  28. package/.codex/agents/copy-orqx.md +4 -65
  29. package/.codex/agents/cost-optimizer.md +4 -0
  30. package/.codex/agents/council-orqx.md +4 -68
  31. package/.codex/agents/courses-orqx.md +4 -64
  32. package/.codex/agents/cro-persuasion.md +4 -0
  33. package/.codex/agents/cyber-orqx.md +4 -67
  34. package/.codex/agents/data-engineer.md +4 -542
  35. package/.codex/agents/design-orqx.md +4 -65
  36. package/.codex/agents/design-system.md +4 -210
  37. package/.codex/agents/developer.md +4 -666
  38. package/.codex/agents/devops.md +4 -668
  39. package/.codex/agents/finance-orqx.md +4 -57
  40. package/.codex/agents/fiscal-compliance-br.md +4 -0
  41. package/.codex/agents/forecast-strategist.md +4 -0
  42. package/.codex/agents/growth-orqx.md +4 -75
  43. package/.codex/agents/hooks-architect.md +2 -2
  44. package/.codex/agents/mcp-integrator.md +2 -2
  45. package/.codex/agents/paidmedia-orqx.md +4 -67
  46. package/.codex/agents/platform-aesthetic-director.md +4 -0
  47. package/.codex/agents/premium-packaging-strategist.md +4 -0
  48. package/.codex/agents/product-lead.md +4 -371
  49. package/.codex/agents/product-orqx.md +4 -57
  50. package/.codex/agents/product-surface-director.md +4 -0
  51. package/.codex/agents/project-integrator.md +2 -2
  52. package/.codex/agents/project-lead.md +4 -414
  53. package/.codex/agents/quality-gate.md +4 -547
  54. package/.codex/agents/research-orqx.md +4 -67
  55. package/.codex/agents/roadmap-sentinel.md +2 -2
  56. package/.codex/agents/skill-craftsman.md +2 -2
  57. package/.codex/agents/snps-orqx.md +4 -684
  58. package/.codex/agents/sop-extractor.md +4 -61
  59. package/.codex/agents/sprint-lead.md +4 -324
  60. package/.codex/agents/squad-creator.md +4 -402
  61. package/.codex/agents/storytelling-orqx.md +4 -65
  62. package/.codex/agents/swarm-orqx.md +4 -64
  63. package/.codex/agents/ux-design-expert.md +4 -532
  64. package/.codex/agents/ux-designer.md +4 -124
  65. package/.codex/command-registry.json +9 -9
  66. package/.codex/delegation-matrix.json +373 -838
  67. package/.codex/delegation-parity.json +657 -0
  68. package/.codex/handoff-packet.parity.schema.json +148 -0
  69. package/.codex/handoff-packet.template.json +26 -0
  70. package/.codex/instructions.md +6 -6
  71. package/.codex/scripts/resolve-codex-agent.js +482 -0
  72. package/.codex/scripts/resolve-codex-command.js +75 -12
  73. package/.codex/scripts/resolve-codex-delegation.js +131 -92
  74. package/.codex/skills/sinapse-claude/SKILL.md +3 -3
  75. package/.codex/skills/sinapse-po/SKILL.md +1 -1
  76. package/.codex/tasks/resolve-sinapse-conflict.md +1 -1
  77. package/.sinapse-ai/cli/commands/health/index.js +24 -0
  78. package/.sinapse-ai/constitution.md +5 -5
  79. package/.sinapse-ai/core/README.md +11 -0
  80. package/.sinapse-ai/core/config/config-loader.js +19 -0
  81. package/.sinapse-ai/core/doctor/checks/git-hooks.js +97 -19
  82. package/.sinapse-ai/core/events/dashboard-emitter.js +30 -9
  83. package/.sinapse-ai/core/execution/build-orchestrator.js +4 -1
  84. package/.sinapse-ai/core/execution/parallel-executor.js +7 -1
  85. package/.sinapse-ai/core/execution/subagent-dispatcher.js +126 -28
  86. package/.sinapse-ai/core/execution/wave-executor.js +4 -1
  87. package/.sinapse-ai/core/grounding/README.md +71 -11
  88. package/.sinapse-ai/core/health-check/checks/project/framework-config.js +38 -2
  89. package/.sinapse-ai/core/health-check/checks/project/package-json.js +47 -3
  90. package/.sinapse-ai/core/health-check/checks/services/gemini-cli.js +117 -0
  91. package/.sinapse-ai/core/health-check/checks/services/index.js +2 -0
  92. package/.sinapse-ai/core/health-check/healers/index.js +40 -3
  93. package/.sinapse-ai/core/ideation/ideation-engine.js +170 -121
  94. package/.sinapse-ai/core/ids/gate-evaluator.js +318 -0
  95. package/.sinapse-ai/core/ids/gates/g5-semantic-handshake.js +190 -0
  96. package/.sinapse-ai/core/ids/gates/g6-ci-integrity.js +162 -0
  97. package/.sinapse-ai/core/ids/index.js +30 -0
  98. package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +11 -0
  99. package/.sinapse-ai/core/orchestration/agent-invoker.js +29 -6
  100. package/.sinapse-ai/core/orchestration/brownfield-handler.js +36 -3
  101. package/.sinapse-ai/core/orchestration/executors/epic-3-executor.js +76 -5
  102. package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +63 -17
  103. package/.sinapse-ai/core/orchestration/executors/epic-6-executor.js +153 -41
  104. package/.sinapse-ai/core/orchestration/executors/epic-executor.js +40 -0
  105. package/.sinapse-ai/core/orchestration/greenfield-handler.js +87 -3
  106. package/.sinapse-ai/core/orchestration/master-orchestrator.js +105 -7
  107. package/.sinapse-ai/core/orchestration/parallel-executor.js +6 -1
  108. package/.sinapse-ai/core/orchestration/workflow-executor.js +41 -0
  109. package/.sinapse-ai/core/registry/squad-agent-resolver.js +253 -0
  110. package/.sinapse-ai/core/telemetry/ids-sink.js +188 -0
  111. package/.sinapse-ai/core/ui/observability-panel.js +240 -0
  112. package/.sinapse-ai/core/utils/output-formatter.js +8 -290
  113. package/.sinapse-ai/core-config.yaml +29 -1
  114. package/.sinapse-ai/data/entity-registry.yaml +15056 -13761
  115. package/.sinapse-ai/development/agents/developer.md +2 -0
  116. package/.sinapse-ai/development/agents/devops.md +9 -0
  117. package/.sinapse-ai/development/agents/snps-orqx.md +12 -22
  118. package/.sinapse-ai/development/external-executors/README.md +18 -0
  119. package/.sinapse-ai/development/external-executors/codex.md +56 -0
  120. package/.sinapse-ai/development/scripts/populate-entity-registry.js +65 -9
  121. package/.sinapse-ai/development/scripts/squad/squad-downloader.js +54 -11
  122. package/.sinapse-ai/development/tasks/build-autonomous.md +11 -1
  123. package/.sinapse-ai/development/tasks/build-resume.md +8 -0
  124. package/.sinapse-ai/development/tasks/build-status.md +8 -0
  125. package/.sinapse-ai/development/tasks/build.md +8 -0
  126. package/.sinapse-ai/development/tasks/cleanup-worktrees.md +8 -1
  127. package/.sinapse-ai/development/tasks/delegate-to-external-executor.md +152 -0
  128. package/.sinapse-ai/development/tasks/github-devops-pre-push-quality-gate.md +46 -29
  129. package/.sinapse-ai/development/tasks/gotcha.md +8 -0
  130. package/.sinapse-ai/development/tasks/gotchas.md +8 -0
  131. package/.sinapse-ai/development/tasks/ids-health.md +14 -6
  132. package/.sinapse-ai/development/tasks/list-mcps.md +15 -0
  133. package/.sinapse-ai/development/tasks/merge-worktree.md +8 -1
  134. package/.sinapse-ai/development/tasks/qa-review-build.md +18 -0
  135. package/.sinapse-ai/development/tasks/remove-mcp.md +8 -1
  136. package/.sinapse-ai/development/tasks/update-sinapse.md +3 -3
  137. package/.sinapse-ai/development/tasks/validate-agents.md +26 -14
  138. package/.sinapse-ai/development/templates/service-template/README.md.hbs +159 -159
  139. package/.sinapse-ai/development/templates/service-template/__tests__/index.test.ts.hbs +238 -238
  140. package/.sinapse-ai/development/templates/service-template/client.ts.hbs +404 -404
  141. package/.sinapse-ai/development/templates/service-template/errors.ts.hbs +183 -183
  142. package/.sinapse-ai/development/templates/service-template/index.ts.hbs +121 -121
  143. package/.sinapse-ai/development/templates/service-template/package.json.hbs +88 -88
  144. package/.sinapse-ai/development/templates/service-template/types.ts.hbs +146 -146
  145. package/.sinapse-ai/development/templates/squad-template/LICENSE +22 -22
  146. package/.sinapse-ai/git-hooks/lib/framework-guard.js +258 -0
  147. package/.sinapse-ai/git-hooks/lib/secret-scanner-core.js +283 -0
  148. package/.sinapse-ai/git-hooks/lib/staged-secret-scan.js +179 -0
  149. package/.sinapse-ai/git-hooks/lib/staged-sql-guard.js +204 -0
  150. package/.sinapse-ai/git-hooks/post-commit +28 -0
  151. package/.sinapse-ai/git-hooks/pre-commit +81 -0
  152. package/.sinapse-ai/git-hooks/pre-push +77 -0
  153. package/.sinapse-ai/hooks/ids-post-commit.js +13 -11
  154. package/.sinapse-ai/hooks/ids-pre-push.js +9 -7
  155. package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +4 -7
  156. package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +4 -7
  157. package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +4 -7
  158. package/.sinapse-ai/infrastructure/integrations/ai-providers/ai-provider-factory.js +4 -1
  159. package/.sinapse-ai/infrastructure/integrations/ai-providers/claude-provider.js +57 -55
  160. package/.sinapse-ai/infrastructure/scripts/codex-parity/resolve.js +161 -0
  161. package/.sinapse-ai/infrastructure/scripts/dashboard-status-writer.js +6 -2
  162. package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +139 -21
  163. package/.sinapse-ai/infrastructure/scripts/ide-sync/persona-renderer.js +97 -0
  164. package/.sinapse-ai/infrastructure/scripts/sync-codex-local-first.js +156 -1
  165. package/.sinapse-ai/infrastructure/scripts/validate-codex-delegation.js +1 -4
  166. package/.sinapse-ai/infrastructure/scripts/validate-codex-integration.js +41 -5
  167. package/.sinapse-ai/infrastructure/templates/coderabbit.yaml.template +280 -280
  168. package/.sinapse-ai/infrastructure/templates/config/env.example +16 -16
  169. package/.sinapse-ai/infrastructure/templates/config/gitignore-additions.tmpl +59 -59
  170. package/.sinapse-ai/infrastructure/templates/github/CODEOWNERS.template +12 -12
  171. package/.sinapse-ai/infrastructure/templates/github-workflows/ci.yml.template +170 -170
  172. package/.sinapse-ai/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -331
  173. package/.sinapse-ai/infrastructure/templates/github-workflows/release.yml.template +197 -197
  174. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +19 -19
  175. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -86
  176. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -146
  177. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-sinapse-base.tmpl +64 -64
  178. package/.sinapse-ai/infrastructure/templates/safe-collab/CODEOWNERS.template +16 -16
  179. package/.sinapse-ai/infrastructure/templates/sinapse-sync.yaml.template +183 -183
  180. package/.sinapse-ai/install-manifest.yaml +239 -223
  181. package/.sinapse-ai/local-config.yaml.template +65 -65
  182. package/.sinapse-ai/product/templates/adr.hbs +126 -126
  183. package/.sinapse-ai/product/templates/dbdr.hbs +242 -242
  184. package/.sinapse-ai/product/templates/epic.hbs +213 -213
  185. package/.sinapse-ai/product/templates/ide-rules/codex-rules.md +30 -0
  186. package/.sinapse-ai/product/templates/pmdr.hbs +187 -187
  187. package/.sinapse-ai/product/templates/prd-v2.0.hbs +217 -217
  188. package/.sinapse-ai/product/templates/prd.hbs +202 -202
  189. package/.sinapse-ai/product/templates/statusline/statusline-script.js +31 -8
  190. package/.sinapse-ai/product/templates/statusline/track-agent-clear.cjs +79 -0
  191. package/.sinapse-ai/product/templates/statusline/track-agent.cjs +218 -0
  192. package/.sinapse-ai/product/templates/story.hbs +264 -264
  193. package/.sinapse-ai/product/templates/task.hbs +171 -171
  194. package/.sinapse-ai/product/templates/tmpl-comment-on-examples.sql +159 -159
  195. package/.sinapse-ai/product/templates/tmpl-migration-script.sql +92 -92
  196. package/.sinapse-ai/product/templates/tmpl-rls-granular-policies.sql +105 -105
  197. package/.sinapse-ai/product/templates/tmpl-rls-kiss-policy.sql +11 -11
  198. package/.sinapse-ai/product/templates/tmpl-rls-roles.sql +136 -136
  199. package/.sinapse-ai/product/templates/tmpl-rls-simple.sql +78 -78
  200. package/.sinapse-ai/product/templates/tmpl-rls-tenant.sql +153 -153
  201. package/.sinapse-ai/product/templates/tmpl-rollback-script.sql +78 -78
  202. package/.sinapse-ai/product/templates/tmpl-seed-data.sql +141 -141
  203. package/.sinapse-ai/product/templates/tmpl-smoke-test.sql +17 -17
  204. package/.sinapse-ai/product/templates/tmpl-staging-copy-merge.sql +140 -140
  205. package/.sinapse-ai/product/templates/tmpl-stored-proc.sql +141 -141
  206. package/.sinapse-ai/product/templates/tmpl-trigger.sql +153 -153
  207. package/.sinapse-ai/product/templates/tmpl-view-materialized.sql +134 -134
  208. package/.sinapse-ai/product/templates/tmpl-view.sql +178 -178
  209. package/.sinapse-ai/scripts/pm.sh +18 -6
  210. package/AGENTS.md +193 -0
  211. package/LICENSE +63 -63
  212. package/README.en.md +17 -18
  213. package/README.md +18 -19
  214. package/bin/cli.js +18 -1
  215. package/bin/commands/agents.js +96 -0
  216. package/bin/commands/doctor.js +15 -0
  217. package/bin/commands/ideate.js +129 -0
  218. package/bin/commands/install.js +194 -22
  219. package/bin/commands/status.js +14 -1
  220. package/bin/commands/uninstall.js +40 -0
  221. package/bin/commands/update.js +52 -0
  222. package/bin/lib/setup-statusline.js +191 -0
  223. package/bin/postinstall.js +50 -4
  224. package/bin/sinapse-init.js +11 -83
  225. package/bin/sinapse.js +146 -2
  226. package/bin/utils/framework-guard.js +17 -4
  227. package/bin/utils/secret-scanner-core.js +283 -0
  228. package/bin/utils/staged-secret-scan.js +106 -40
  229. package/bin/utils/staged-sql-guard.js +204 -0
  230. package/bin/utils/validate-publish.js +63 -0
  231. package/docs/agent-reference-guide.md +4 -6
  232. package/docs/framework/agent-prefix-convention.md +58 -0
  233. package/docs/framework/collaboration-activation.md +45 -0
  234. package/docs/security/overview.md +1 -1
  235. package/package.json +16 -8
  236. package/packages/installer/src/index.js +26 -0
  237. package/packages/installer/src/installer/git-hooks-installer.js +546 -0
  238. package/packages/installer/src/installer/sinapse-ai-installer.js +87 -0
  239. package/packages/installer/src/wizard/feedback.js +1 -1
  240. package/packages/installer/src/wizard/ide-config-generator.js +40 -25
  241. package/packages/installer/src/wizard/index.js +50 -0
  242. package/packages/installer/src/wizard/validators.js +38 -1
  243. package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +24 -1
  244. package/packages/installer/tests/unit/doctor/doctor-checks.test.js +42 -3
  245. package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +10 -4
  246. package/packages/installer/tests/unit/git-hooks-installer.test.js +262 -0
  247. package/packages/sinapse-install/bin/edmcp.js +0 -0
  248. package/packages/sinapse-install/bin/sinapse-install.js +0 -0
  249. package/scripts/audit-tasks.cjs +112 -91
  250. package/scripts/check-markdown-links.py +352 -352
  251. package/scripts/eval-runner.js +422 -0
  252. package/scripts/generate-install-manifest.js +13 -9
  253. package/scripts/generate-synapse-runtime.js +51 -0
  254. package/scripts/prepare-hooks.js +58 -0
  255. package/scripts/regenerate-orqx-stubs.ps1 +2 -2
  256. package/scripts/validate-agents-md.js +128 -0
  257. package/scripts/validate-all.js +2 -0
  258. package/scripts/validate-evals.js +466 -0
  259. package/scripts/validate-schemas.js +539 -0
  260. package/scripts/validate-squad-orqx.js +9 -2
  261. package/sinapse/agents/sinapse-orqx.md +12 -22
  262. package/sinapse/agents/snps-orqx.md +11 -21
  263. package/squads/claude-code-mastery/squad.yaml +8 -0
  264. package/squads/squad-animations/squad.yaml +1 -1
  265. package/squads/squad-brand/squad.yaml +1 -1
  266. package/squads/squad-cloning/squad.yaml +1 -1
  267. package/squads/squad-commercial/squad.yaml +2 -3
  268. package/squads/squad-content/squad.yaml +1 -1
  269. package/squads/squad-copy/squad.yaml +2 -3
  270. package/squads/squad-courses/squad.yaml +1 -1
  271. package/squads/squad-cybersecurity/squad.yaml +2 -3
  272. package/squads/{squad-artdir → squad-design}/agents/cro-persuasion.md +1 -1
  273. package/squads/{squad-artdir → squad-design}/agents/platform-aesthetic-director.md +2 -2
  274. package/squads/{squad-artdir → squad-design}/agents/premium-packaging-strategist.md +2 -2
  275. package/squads/{squad-artdir → squad-design}/agents/product-surface-director.md +3 -3
  276. package/squads/squad-design/squad.yaml +6 -3
  277. package/squads/squad-finance/squad.yaml +7 -1
  278. package/squads/squad-growth/squad.yaml +1 -1
  279. package/squads/squad-paidmedia/squad.yaml +2 -3
  280. package/squads/squad-product/squad.yaml +1 -1
  281. package/squads/squad-research/squad.yaml +2 -3
  282. package/squads/squad-storytelling/squad.yaml +2 -3
  283. package/.codex/agents/brad-frost.md +0 -46
  284. package/.codex/agents/claude-orqx.md +0 -72
  285. package/.codex/agents/copy-chief.md +0 -162
  286. package/.codex/agents/cyber-chief.md +0 -169
  287. package/.codex/agents/dan-mall.md +0 -43
  288. package/.codex/agents/data-chief.md +0 -198
  289. package/.codex/agents/dave-malouf.md +0 -43
  290. package/.codex/agents/db-sage.md +0 -152
  291. package/.codex/agents/design-chief.md +0 -226
  292. package/.codex/agents/dev.md +0 -102
  293. package/.codex/agents/legal-chief.md +0 -199
  294. package/.codex/agents/nano-banana-generator.md +0 -42
  295. package/.codex/agents/pm.md +0 -81
  296. package/.codex/agents/po.md +0 -85
  297. package/.codex/agents/qa.md +0 -98
  298. package/.codex/agents/sm.md +0 -77
  299. package/.codex/agents/squad-chief.md +0 -1553
  300. package/.codex/agents/squad.md +0 -66
  301. package/.codex/agents/story-chief.md +0 -180
  302. package/.codex/agents/tools-orqx.md +0 -219
  303. package/.codex/agents/traffic-masters-chief.md +0 -211
  304. package/.sinapse-ai/data/registry-update-log.jsonl +0 -72
  305. package/.sinapse-ai/development/scripts/elicitation-engine.js +0 -385
  306. package/.sinapse-ai/development/scripts/elicitation-session-manager.js +0 -300
  307. package/.sinapse-ai/development/tasks/test-validation-task.md +0 -172
  308. package/.sinapse-ai/monitor/hooks/lib/__init__.py +0 -2
  309. package/.sinapse-ai/monitor/hooks/lib/enrich.py +0 -59
  310. package/.sinapse-ai/monitor/hooks/lib/send_event.py +0 -48
  311. package/.sinapse-ai/monitor/hooks/notification.py +0 -30
  312. package/.sinapse-ai/monitor/hooks/post_tool_use.py +0 -46
  313. package/.sinapse-ai/monitor/hooks/pre_compact.py +0 -30
  314. package/.sinapse-ai/monitor/hooks/pre_tool_use.py +0 -41
  315. package/.sinapse-ai/monitor/hooks/stop.py +0 -30
  316. package/.sinapse-ai/monitor/hooks/subagent_stop.py +0 -30
  317. package/.sinapse-ai/monitor/hooks/user_prompt_submit.py +0 -39
  318. package/.sinapse-ai/product/templates/statusline/track-agent.sh +0 -69
  319. package/bin/sinapse-graph.js +0 -19
  320. package/docs/codex-integration-process.md +0 -22
  321. package/docs/codex-parity-program.md +0 -27
  322. package/scripts/install-monitor-hooks.sh +0 -82
  323. package/squads/squad-artdir/README.md +0 -90
  324. package/squads/squad-artdir/agents/accessibility-guardian.md +0 -184
  325. package/squads/squad-artdir/agents/artdir-orqx.md +0 -222
  326. package/squads/squad-artdir/agents/color-psychologist.md +0 -166
  327. package/squads/squad-artdir/agents/design-system-architect.md +0 -100
  328. package/squads/squad-artdir/agents/ia-architect.md +0 -169
  329. package/squads/squad-artdir/agents/interaction-designer.md +0 -162
  330. package/squads/squad-artdir/agents/layout-engineer.md +0 -163
  331. package/squads/squad-artdir/agents/motion-architect.md +0 -185
  332. package/squads/squad-artdir/agents/type-systemist.md +0 -138
  333. package/squads/squad-artdir/agents/visual-strategist.md +0 -127
  334. package/squads/squad-artdir/checklists/seven-pillars-validation-checklist.md +0 -172
  335. package/squads/squad-artdir/knowledge-base/case-nyo-ia-reference.md +0 -289
  336. package/squads/squad-artdir/knowledge-base/deliverables-templates.md +0 -457
  337. package/squads/squad-artdir/knowledge-base/motion-technique-catalog.md +0 -247
  338. package/squads/squad-artdir/knowledge-base/premium-packaging-principles.md +0 -133
  339. package/squads/squad-artdir/knowledge-base/psychological-toolkit.md +0 -229
  340. package/squads/squad-artdir/knowledge-base/saas-art-direction-canon.md +0 -242
  341. package/squads/squad-artdir/knowledge-base/seven-pillars-framework.md +0 -289
  342. package/squads/squad-artdir/knowledge-base/ten-pillars-framework.md +0 -221
  343. package/squads/squad-artdir/package.json +0 -20
  344. package/squads/squad-artdir/squad.yaml +0 -299
  345. package/squads/squad-artdir/tasks/audit-conversion.md +0 -97
  346. package/squads/squad-artdir/tasks/audit-drift-multi-surface.md +0 -55
  347. package/squads/squad-artdir/tasks/consult-saas-canon.md +0 -54
  348. package/squads/squad-artdir/tasks/create-art-direction-brief.md +0 -110
  349. package/squads/squad-artdir/tasks/create-premium-packaging-brief.md +0 -61
  350. package/squads/squad-artdir/tasks/create-wireflow.md +0 -84
  351. package/squads/squad-artdir/tasks/design-color-system.md +0 -81
  352. package/squads/squad-artdir/tasks/design-product-surface.md +0 -60
  353. package/squads/squad-artdir/tasks/design-token-system.md +0 -58
  354. package/squads/squad-artdir/tasks/diagnose-visual-language.md +0 -92
  355. package/squads/squad-artdir/tasks/first-5-minutes-choreography.md +0 -65
  356. package/squads/squad-artdir/tasks/specify-motion-system.md +0 -84
  357. package/squads/squad-artdir/tasks/validate-against-pillars.md +0 -143
  358. package/squads/squad-artdir/templates/art-direction-brief-template.md +0 -215
  359. package/squads/squad-artdir/workflows/conversion-audit-cycle.yaml +0 -142
  360. package/squads/squad-artdir/workflows/full-art-direction-cycle.yaml +0 -179
  361. package/squads/squad-artdir/workflows/saas-platform-art-direction-cycle.yaml +0 -338
  362. package/squads/squad-commercial/agents/legal-chief.md +0 -199
  363. package/squads/squad-copy/agents/copy-chief.md +0 -162
  364. package/squads/squad-cybersecurity/agents/cyber-chief.md +0 -169
  365. package/squads/squad-design/agents/design-chief.md +0 -226
  366. package/squads/squad-paidmedia/agents/traffic-masters-chief.md +0 -211
  367. package/squads/squad-research/agents/data-chief.md +0 -198
  368. package/squads/squad-storytelling/agents/story-chief.md +0 -180
@@ -0,0 +1,179 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Staged Secret Scan — git pre-commit guard.
5
+ *
6
+ * Reads EXCLUSIVELY the staged blob of each changed file (`git show :<path>`),
7
+ * so only what is actually being committed is measured (the working-tree copy,
8
+ * which may differ, is never read — no stash dance required).
9
+ *
10
+ * Detection is delegated to the shared core (`secret-scanner-core.js`):
11
+ * - all 20+ named patterns
12
+ * - Shannon-entropy backstop for unnamed high-entropy tokens
13
+ * - placeholder allowlist (.env.example values, your-key-here, CHANGEME, …)
14
+ * - lockfile-hash context allowlist
15
+ * - redacted output (secrets never printed in full)
16
+ *
17
+ * fail-CLOSED: if the scanner cannot run (load error, git error mid-scan), the
18
+ * commit is BLOCKED (exit 1) rather than silently allowed.
19
+ *
20
+ * @module bin/utils/staged-secret-scan
21
+ */
22
+
23
+ const path = require('path');
24
+ const { execFileSync, execSync } = require('child_process');
25
+
26
+ let core;
27
+ try {
28
+ core = require(path.join(__dirname, 'secret-scanner-core.js'));
29
+ } catch (err) {
30
+ // fail-CLOSED: the scanner itself is broken — refuse to let a commit through
31
+ // unscanned.
32
+ process.stderr.write('\nStaged Secret Scan: scanner failed to load — commit blocked (fail-closed).\n');
33
+ process.stderr.write(String(err && err.message ? err.message : err) + '\n');
34
+ process.exit(1);
35
+ }
36
+
37
+ const { scanContent, redactMatch } = core;
38
+
39
+ const BLOCKED_ENV_FILE_PATTERN = /(^|\/)\.env(\..+)?$/i;
40
+ const SAFE_ENV_FILE_PATTERN = /(^|\/)\.env\.(example|sample|template)$/i;
41
+
42
+ // Files that legitimately carry secret-shaped strings by design:
43
+ // - the scanner's own source (named-pattern regexes embed token shapes like
44
+ // the JWT header), which would otherwise self-trip the entropy backstop;
45
+ // - any test/spec file (intentional fixtures that prove detection works).
46
+ // These are PATH-exempt so the guard never blocks committing the guard itself
47
+ // or its tests. All production code paths remain fully scanned.
48
+ const SCANNER_SELF_FILES = new Set([
49
+ 'bin/utils/secret-scanner-core.js',
50
+ 'bin/utils/staged-secret-scan.js',
51
+ '.claude/hooks/secret-scanning.cjs',
52
+ ]);
53
+ const TEST_FILE_PATTERN = /(^|\/)(tests?|__tests__)\/|\.(test|spec)\.[cm]?[jt]s$/i;
54
+
55
+ function isScanExemptPath(filePath) {
56
+ const norm = String(filePath).replace(/\\/g, '/');
57
+ return SCANNER_SELF_FILES.has(norm) || TEST_FILE_PATTERN.test(norm);
58
+ }
59
+
60
+ /**
61
+ * Back-compat shim: the previous public API exposed { SECRET_PATTERNS,
62
+ * findSecretMatches }. They now resolve through the shared core so any external
63
+ * importer keeps working while gaining the hardened detection.
64
+ */
65
+ const SECRET_PATTERNS = core.NAMED_PATTERNS.map((p) => ({ label: p.name, pattern: p.pattern }));
66
+
67
+ function findSecretMatches(content, filePath) {
68
+ return scanContent(content, { filePath: filePath || '' }).map((f) => f.name);
69
+ }
70
+
71
+ function getStagedFiles() {
72
+ try {
73
+ const output = execSync('git diff --cached --name-only --diff-filter=ACMR', {
74
+ encoding: 'utf8',
75
+ stdio: ['ignore', 'pipe', 'pipe'],
76
+ }).trim();
77
+ return output ? output.split('\n').filter(Boolean) : [];
78
+ } catch {
79
+ return [];
80
+ }
81
+ }
82
+
83
+ function isBlockedEnvFile(filePath) {
84
+ return BLOCKED_ENV_FILE_PATTERN.test(filePath) && !SAFE_ENV_FILE_PATTERN.test(filePath);
85
+ }
86
+
87
+ function readStagedFile(filePath) {
88
+ // Throws on failure so the caller can fail-CLOSED instead of scanning "".
89
+ return execFileSync('git', ['show', `:${filePath}`], {
90
+ encoding: 'utf8',
91
+ stdio: ['ignore', 'pipe', 'pipe'],
92
+ maxBuffer: 5 * 1024 * 1024,
93
+ });
94
+ }
95
+
96
+ function scanStagedFiles(files) {
97
+ const findings = [];
98
+
99
+ for (const filePath of files) {
100
+ // A non-safe .env file is blocked outright (its values are real by design).
101
+ if (isBlockedEnvFile(filePath)) {
102
+ findings.push({ filePath, reason: 'environment file (use .env.example with placeholders)', redacted: null });
103
+ continue;
104
+ }
105
+
106
+ // Skip the scanner's own source + any test/spec file (intentional fixtures).
107
+ if (isScanExemptPath(filePath)) {
108
+ continue;
109
+ }
110
+
111
+ let content;
112
+ try {
113
+ content = readStagedFile(filePath);
114
+ } catch {
115
+ // Could not read the staged blob (binary, deleted-then-readded race, etc.)
116
+ // — skip silently; binary/secret content of unreadable blobs is rare and
117
+ // the named .env rule above already covers the common dotfile leak.
118
+ continue;
119
+ }
120
+
121
+ const matches = scanContent(content, { filePath });
122
+ for (const match of matches) {
123
+ findings.push({ filePath, reason: match.name, redacted: match.redacted, entropy: match.entropy });
124
+ }
125
+ }
126
+
127
+ return findings;
128
+ }
129
+
130
+ function main() {
131
+ let stagedFiles;
132
+ let findings;
133
+ try {
134
+ stagedFiles = getStagedFiles();
135
+ if (stagedFiles.length === 0) {
136
+ process.exit(0);
137
+ }
138
+ findings = scanStagedFiles(stagedFiles);
139
+ } catch (err) {
140
+ // fail-CLOSED on any unexpected scanner error.
141
+ console.error('');
142
+ console.error('Staged Secret Scan: unexpected error — commit blocked (fail-closed).');
143
+ console.error(String(err && err.message ? err.message : err));
144
+ console.error('');
145
+ process.exit(1);
146
+ }
147
+
148
+ if (findings.length === 0) {
149
+ process.exit(0);
150
+ }
151
+
152
+ console.error('');
153
+ console.error('Staged Secret Scan: commit blocked.');
154
+ console.error('');
155
+ for (const finding of findings) {
156
+ const sample = finding.redacted ? ` [${finding.redacted}]` : '';
157
+ const ent = finding.entropy ? ` (entropy ${finding.entropy})` : '';
158
+ console.error(`- ${finding.filePath}: ${finding.reason}${sample}${ent}`);
159
+ }
160
+ console.error('');
161
+ console.error('Remove the sensitive content before committing.');
162
+ console.error('Use .env (gitignored) for local dev and .env.example with placeholders for templates.');
163
+ console.error('');
164
+ process.exit(1);
165
+ }
166
+
167
+ module.exports = {
168
+ SECRET_PATTERNS,
169
+ findSecretMatches,
170
+ getStagedFiles,
171
+ isBlockedEnvFile,
172
+ isScanExemptPath,
173
+ scanStagedFiles,
174
+ redactMatch,
175
+ };
176
+
177
+ if (require.main === module) {
178
+ main();
179
+ }
@@ -0,0 +1,204 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Staged SQL Guard — git pre-commit guard for destructive DDL/DML.
5
+ *
6
+ * Ports the DANGEROUS_PATTERNS from `.claude/hooks/sql-governance.py` (which is
7
+ * IDE-bound: it only fires on Claude Code Bash tool calls) into an IDE-agnostic
8
+ * Node guard that runs at the git layer. It scans the STAGED blob of every
9
+ * changed `.sql` / migration-bearing file and BLOCKS the commit (exit 1) if it
10
+ * finds destructive schema/data operations:
11
+ *
12
+ * - DROP TABLE/VIEW/FUNCTION/TRIGGER/INDEX/SCHEMA/POLICY
13
+ * - TRUNCATE
14
+ * - DELETE ... (without a WHERE clause)
15
+ * - CREATE TABLE ... AS SELECT (disallowed backup pattern)
16
+ *
17
+ * Scope decision: this guard targets the genuinely IRREVERSIBLE / data-loss
18
+ * operations (the same ones a destructive migration would carry). Plain
19
+ * CREATE/ALTER are intentionally NOT blocked at the git layer — they are the
20
+ * normal content of forward migrations and blocking them would make every
21
+ * legitimate schema change require `--no-verify`. The Claude-Code-level
22
+ * sql-governance.py still gates CREATE/ALTER at authoring time interactively.
23
+ *
24
+ * Only `.sql` files and files under a `migrations/` path are scanned, so SQL
25
+ * embedded in prose/docs or string literals in application code does not trip
26
+ * the guard. SQL comments (line and block) are stripped before matching.
27
+ *
28
+ * fail-CLOSED on scanner error (a broken guard must never silently pass
29
+ * destructive SQL). fail-OPEN only when there is genuinely nothing to scan.
30
+ *
31
+ * @module bin/utils/staged-sql-guard
32
+ */
33
+
34
+ const { execFileSync, execSync } = require('child_process');
35
+
36
+ /**
37
+ * Destructive patterns. Mirrors the irreversible subset of
38
+ * sql-governance.py DANGEROUS_PATTERNS. Each entry: [regex, humanLabel].
39
+ * Regexes are case-insensitive and operate on comment-stripped SQL text.
40
+ * @constant {Array<[RegExp, string]>}
41
+ */
42
+ const DANGEROUS_PATTERNS = [
43
+ // DDL — destructive drops
44
+ [/\bDROP\s+TABLE\b/i, 'DROP TABLE'],
45
+ [/\bDROP\s+VIEW\b/i, 'DROP VIEW'],
46
+ [/\bDROP\s+MATERIALIZED\s+VIEW\b/i, 'DROP MATERIALIZED VIEW'],
47
+ [/\bDROP\s+FUNCTION\b/i, 'DROP FUNCTION'],
48
+ [/\bDROP\s+TRIGGER\b/i, 'DROP TRIGGER'],
49
+ [/\bDROP\s+INDEX\b/i, 'DROP INDEX'],
50
+ [/\bDROP\s+SCHEMA\b/i, 'DROP SCHEMA'],
51
+ [/\bDROP\s+POLICY\b/i, 'DROP POLICY'],
52
+ [/\bDROP\s+DATABASE\b/i, 'DROP DATABASE'],
53
+ // DML — data loss
54
+ [/\bTRUNCATE\b/i, 'TRUNCATE'],
55
+ // DELETE without a WHERE clause (whole-table wipe).
56
+ [/\bDELETE\s+FROM\s+[^;]*?(?:;|$)(?<!\bWHERE\b[^;]*)/i, 'DELETE without WHERE'],
57
+ // Disallowed backup pattern (table copy).
58
+ [/\bCREATE\s+TABLE\b[\s\S]*?\bAS\s+SELECT\b/i, 'CREATE TABLE AS SELECT (backup pattern)'],
59
+ ];
60
+
61
+ const SQL_FILE_PATTERN = /\.sql$/i;
62
+ const MIGRATION_PATH_PATTERN = /(^|\/)migrations?\//i;
63
+
64
+ /**
65
+ * Should this path be SQL-scanned?
66
+ * @param {string} filePath
67
+ * @returns {boolean}
68
+ */
69
+ function isSqlScanTarget(filePath) {
70
+ const norm = String(filePath).replace(/\\/g, '/');
71
+ return SQL_FILE_PATTERN.test(norm) || MIGRATION_PATH_PATTERN.test(norm);
72
+ }
73
+
74
+ /**
75
+ * Strip SQL comments so `-- DROP TABLE foo` (commented out) is ignored.
76
+ * Removes `--` line comments and `/* ... *\/` block comments.
77
+ * @param {string} sql
78
+ * @returns {string}
79
+ */
80
+ function stripSqlComments(sql) {
81
+ return String(sql == null ? '' : sql)
82
+ .replace(/\/\*[\s\S]*?\*\//g, ' ') // block comments
83
+ .replace(/--[^\n\r]*/g, ' '); // line comments
84
+ }
85
+
86
+ /**
87
+ * Detect destructive SQL in a blob. Operates per-statement (split on ';') so a
88
+ * `DELETE FROM a WHERE x; DELETE FROM b;` correctly flags only the second.
89
+ * @param {string} content
90
+ * @returns {string[]} list of human labels for findings (deduped)
91
+ */
92
+ function detectDangerousSql(content) {
93
+ const cleaned = stripSqlComments(content);
94
+ const statements = cleaned.split(';');
95
+ const found = new Set();
96
+
97
+ for (const rawStmt of statements) {
98
+ const stmt = rawStmt.trim();
99
+ if (!stmt) continue;
100
+
101
+ for (const [pattern, label] of DANGEROUS_PATTERNS) {
102
+ if (label === 'DELETE without WHERE') {
103
+ // Per-statement WHERE check: flag a DELETE FROM only when this
104
+ // statement has no WHERE.
105
+ if (/\bDELETE\s+FROM\b/i.test(stmt) && !/\bWHERE\b/i.test(stmt)) {
106
+ found.add(label);
107
+ }
108
+ continue;
109
+ }
110
+ if (pattern.test(stmt)) {
111
+ found.add(label);
112
+ }
113
+ }
114
+ }
115
+
116
+ return Array.from(found);
117
+ }
118
+
119
+ function getStagedFiles() {
120
+ try {
121
+ const output = execSync('git diff --cached --name-only --diff-filter=ACMR', {
122
+ encoding: 'utf8',
123
+ stdio: ['ignore', 'pipe', 'pipe'],
124
+ }).trim();
125
+ return output ? output.split('\n').filter(Boolean) : [];
126
+ } catch {
127
+ return [];
128
+ }
129
+ }
130
+
131
+ function readStagedFile(filePath) {
132
+ // Throws on failure so the caller can fail-CLOSED instead of scanning "".
133
+ return execFileSync('git', ['show', `:${filePath}`], {
134
+ encoding: 'utf8',
135
+ stdio: ['ignore', 'pipe', 'pipe'],
136
+ maxBuffer: 5 * 1024 * 1024,
137
+ });
138
+ }
139
+
140
+ /**
141
+ * Scan the given staged files for destructive SQL.
142
+ * @param {string[]} files
143
+ * @returns {Array<{ filePath: string, reasons: string[] }>}
144
+ */
145
+ function scanStagedFiles(files) {
146
+ const findings = [];
147
+
148
+ for (const filePath of files) {
149
+ if (!isSqlScanTarget(filePath)) continue;
150
+
151
+ let content;
152
+ try {
153
+ content = readStagedFile(filePath);
154
+ } catch {
155
+ // Unreadable blob (binary/deleted-readded race) — skip; SQL files are text.
156
+ continue;
157
+ }
158
+
159
+ const reasons = detectDangerousSql(content);
160
+ if (reasons.length > 0) {
161
+ findings.push({ filePath, reasons });
162
+ }
163
+ }
164
+
165
+ return findings;
166
+ }
167
+
168
+ function main() {
169
+ let findings;
170
+ try {
171
+ const files = getStagedFiles();
172
+ if (files.length === 0) process.exit(0);
173
+ findings = scanStagedFiles(files);
174
+ } catch (err) {
175
+ // fail-CLOSED on unexpected scanner error.
176
+ process.stderr.write('\nStaged SQL Guard: unexpected error — commit blocked (fail-closed).\n');
177
+ process.stderr.write(String(err && err.message ? err.message : err) + '\n');
178
+ process.exit(1);
179
+ }
180
+
181
+ if (findings.length === 0) process.exit(0);
182
+
183
+ process.stderr.write('\nStaged SQL Guard: commit blocked (destructive SQL detected).\n\n');
184
+ for (const f of findings) {
185
+ process.stderr.write(`- ${f.filePath}: ${f.reasons.join(', ')}\n`);
186
+ }
187
+ process.stderr.write('\nDestructive schema/data operations must go through a reviewed migration,\n');
188
+ process.stderr.write('not a raw commit. If this is an intentional, reviewed migration:\n');
189
+ process.stderr.write(' git commit --no-verify (framework contributors / reviewed migrations only)\n\n');
190
+ process.exit(1);
191
+ }
192
+
193
+ module.exports = {
194
+ DANGEROUS_PATTERNS,
195
+ isSqlScanTarget,
196
+ stripSqlComments,
197
+ detectDangerousSql,
198
+ getStagedFiles,
199
+ scanStagedFiles,
200
+ };
201
+
202
+ if (require.main === module) {
203
+ main();
204
+ }
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /* SINAPSE-MANAGED-GIT-HOOK — Auto-generated by SINAPSE git-hooks-installer. Do not edit manually. */
4
+ /* Re-run `sinapse init` (or the greenfield bootstrap) to regenerate. */
5
+
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const { spawnSync } = require('child_process');
9
+
10
+ const projectRoot = process.cwd();
11
+
12
+ // Migrated from .husky/post-commit (non-blocking, best-effort).
13
+ const POST_COMMIT_SCRIPTS = [
14
+ path.join('.sinapse-ai', 'infrastructure', 'scripts', 'git-hooks', 'post-commit.js'),
15
+ path.join('.sinapse-ai', 'hooks', 'ids-post-commit.js'),
16
+ ];
17
+
18
+ for (const rel of POST_COMMIT_SCRIPTS) {
19
+ const abs = path.join(projectRoot, rel);
20
+ if (!fs.existsSync(abs)) continue;
21
+ try {
22
+ spawnSync(process.execPath, [abs], { stdio: 'ignore', cwd: projectRoot });
23
+ } catch {
24
+ // Never block on post-commit failures.
25
+ }
26
+ }
27
+
28
+ process.exit(0);
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /* SINAPSE-MANAGED-GIT-HOOK — Auto-generated by SINAPSE git-hooks-installer. Do not edit manually. */
4
+ /* Re-run `sinapse init` (or the greenfield bootstrap) to regenerate. */
5
+
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const { spawnSync } = require('child_process');
9
+
10
+ const projectRoot = process.cwd();
11
+ const libDir = path.join(__dirname, 'lib');
12
+
13
+ // --- 1-3. SINAPSE staged guards (each fail-CLOSED) ---------------------------
14
+ // Order: secret scan, then destructive-SQL guard, then framework-boundary guard.
15
+ // framework-guard self-disables when boundary.frameworkProtection is false.
16
+ const GUARDS = [
17
+ { file: 'staged-secret-scan.js', label: 'Secret Scan' },
18
+ { file: 'staged-sql-guard.js', label: 'SQL Guard' },
19
+ { file: 'framework-guard.js', label: 'Framework Boundary' },
20
+ ];
21
+
22
+ for (const guard of GUARDS) {
23
+ const guardPath = path.join(libDir, guard.file);
24
+ if (!fs.existsSync(guardPath)) {
25
+ // A bundled guard vanished — fail-CLOSED rather than skip silently.
26
+ process.stderr.write('SINAPSE ' + guard.label + ': guard missing at ' + guardPath + ' — blocking commit (fail-closed).\n');
27
+ process.exit(1);
28
+ }
29
+ const res = spawnSync(process.execPath, [guardPath], { stdio: 'inherit', cwd: projectRoot });
30
+ if (res.error) {
31
+ process.stderr.write('SINAPSE ' + guard.label + ': guard failed to run — blocking commit (fail-closed).\n');
32
+ process.stderr.write(' ' + res.error.message + '\n');
33
+ process.exit(1);
34
+ }
35
+ if (typeof res.status === 'number' && res.status !== 0) {
36
+ // Non-zero from a guard = commit blocked. A clean guard prints its own
37
+ // reason; a crashed guard (e.g. corrupted lib) does not, so emit an
38
+ // explicit fail-closed line so the block is never silent.
39
+ process.stderr.write('SINAPSE ' + guard.label + ': blocking commit (fail-closed, exit ' + res.status + ').\n');
40
+ process.exit(res.status);
41
+ }
42
+ }
43
+
44
+ // --- 4. Chain to a pre-existing hook (husky or backed-up prior hook) --------
45
+ const explicitChain = null;
46
+ const candidates = [];
47
+ if (explicitChain) {
48
+ candidates.push(path.resolve(projectRoot, explicitChain));
49
+ }
50
+ candidates.push(path.join(projectRoot, '.husky', 'pre-commit'));
51
+
52
+ const selfPath = __filename;
53
+ for (const candidate of candidates) {
54
+ if (!candidate || !fs.existsSync(candidate)) continue;
55
+ if (path.resolve(candidate) === path.resolve(selfPath)) continue; // never recurse into self
56
+
57
+ const isJs = candidate.endsWith('.js') || candidate.endsWith('.cjs');
58
+ const cmd = isJs ? process.execPath : candidate;
59
+ const args = isJs ? [candidate] : [];
60
+ const res = spawnSync(cmd, args, { stdio: 'inherit', cwd: projectRoot });
61
+
62
+ if (res.error) {
63
+ // A shell-script hook (.husky uses sh) may not be directly executable via
64
+ // spawnSync on Windows. Try 'sh' as an interpreter before giving up.
65
+ if (!isJs) {
66
+ const shRes = spawnSync('sh', [candidate], { stdio: 'inherit', cwd: projectRoot });
67
+ if (!shRes.error) {
68
+ if (typeof shRes.status === 'number' && shRes.status !== 0) process.exit(shRes.status);
69
+ break;
70
+ }
71
+ }
72
+ process.stderr.write('SINAPSE pre-commit: failed to run chained hook ' + candidate + ': ' + res.error.message + '\n');
73
+ process.exit(1);
74
+ }
75
+ if (typeof res.status === 'number' && res.status !== 0) {
76
+ process.exit(res.status);
77
+ }
78
+ break; // only chain to the first existing prior hook
79
+ }
80
+
81
+ process.exit(0);
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /* SINAPSE-MANAGED-GIT-HOOK — Auto-generated by SINAPSE git-hooks-installer. Do not edit manually. */
4
+ /* Re-run `sinapse init` (or the greenfield bootstrap) to regenerate. */
5
+
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const { spawnSync } = require('child_process');
9
+
10
+ const projectRoot = process.cwd();
11
+
12
+ // --- 1. Run validate:all (or validate) if the project defines it -----------
13
+ function pickValidateScript() {
14
+ try {
15
+ const pkgPath = path.join(projectRoot, 'package.json');
16
+ if (!fs.existsSync(pkgPath)) return null;
17
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
18
+ const scripts = (pkg && pkg.scripts) || {};
19
+ for (const name of ['validate:all', 'validate']) {
20
+ if (typeof scripts[name] === 'string' && scripts[name].length > 0) return name;
21
+ }
22
+ } catch {
23
+ // Unreadable package.json — treat as "no validate script" (allow).
24
+ }
25
+ return null;
26
+ }
27
+
28
+ const script = pickValidateScript();
29
+ if (script) {
30
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
31
+ const res = spawnSync(npmCmd, ['run', '--silent', script], { stdio: 'inherit', cwd: projectRoot });
32
+ if (res.error) {
33
+ process.stderr.write('SINAPSE pre-push: could not run "npm run ' + script + '" — blocking push (fail-closed).\n');
34
+ process.stderr.write(' ' + res.error.message + '\n');
35
+ process.stderr.write(' Bypass (emergency only): git push --no-verify\n');
36
+ process.exit(1);
37
+ }
38
+ if (typeof res.status === 'number' && res.status !== 0) {
39
+ process.stderr.write('\nSINAPSE pre-push: validation failed (see output above). Push blocked.\n');
40
+ process.stderr.write(' Bypass (emergency only): git push --no-verify\n\n');
41
+ process.exit(res.status);
42
+ }
43
+ }
44
+
45
+ // --- 2. Chain to a pre-existing pre-push hook ------------------------------
46
+ const explicitChain = ".husky\\pre-push";
47
+ const candidates = [];
48
+ if (explicitChain) {
49
+ candidates.push(path.resolve(projectRoot, explicitChain));
50
+ }
51
+ candidates.push(path.join(projectRoot, '.husky', 'pre-push'));
52
+
53
+ const selfPath = __filename;
54
+ for (const candidate of candidates) {
55
+ if (!candidate || !fs.existsSync(candidate)) continue;
56
+ if (path.resolve(candidate) === path.resolve(selfPath)) continue;
57
+
58
+ const isJs = candidate.endsWith('.js') || candidate.endsWith('.cjs');
59
+ const cmd = isJs ? process.execPath : candidate;
60
+ const args = isJs ? [candidate] : [];
61
+ const res = spawnSync(cmd, args, { stdio: 'inherit', cwd: projectRoot });
62
+ if (res.error) {
63
+ if (!isJs) {
64
+ const shRes = spawnSync('sh', [candidate], { stdio: 'inherit', cwd: projectRoot });
65
+ if (!shRes.error) {
66
+ if (typeof shRes.status === 'number' && shRes.status !== 0) process.exit(shRes.status);
67
+ break;
68
+ }
69
+ }
70
+ process.stderr.write('SINAPSE pre-push: failed to run chained hook ' + candidate + ': ' + res.error.message + '\n');
71
+ process.exit(1);
72
+ }
73
+ if (typeof res.status === 'number' && res.status !== 0) process.exit(res.status);
74
+ break;
75
+ }
76
+
77
+ process.exit(0);
@@ -96,17 +96,19 @@ async function main() {
96
96
  }
97
97
 
98
98
  try {
99
- const { RegistryUpdater } = require(path.resolve(REPO_ROOT, '.sinapse-ai/core/ids/registry-updater.js'));
100
- const updater = new RegistryUpdater();
101
- const result = await updater.processChanges(changes);
102
-
103
- if (result.updated > 0) {
104
- console.log(`[IDS-Hook] Registry updated: ${result.updated} entities processed.`);
105
- }
106
-
107
- if (result.errors.length > 0) {
108
- console.warn(`[IDS-Hook] ${result.errors.length} errors during update.`);
109
- }
99
+ // Use the canonical deterministic generator (populate-entity-registry.js),
100
+ // NOT the incremental RegistryUpdater. The updater emits a divergent schema
101
+ // (categories-first, dropping the metadata/resolutionRate block) which
102
+ // flipped the entire ~30k-line registry on every commit — the recurring
103
+ // drift. populate() is a fixed point: it preserves lastUpdated/lastVerified
104
+ // when content is unchanged, so an unchanged repo regenerates byte-identical
105
+ // (zero churn).
106
+ const { populate } = require(
107
+ path.resolve(REPO_ROOT, '.sinapse-ai/development/scripts/populate-entity-registry.js'),
108
+ );
109
+ const registry = populate();
110
+ const count = registry && registry.metadata ? registry.metadata.entityCount : 0;
111
+ console.log(`[IDS-Hook] Registry regenerated (canonical schema, ${count} entities).`);
110
112
  } catch (err) {
111
113
  // Post-commit hook should NEVER block workflow
112
114
  console.error(`[IDS-Hook] Registry update failed (non-blocking): ${err.message}`);
@@ -105,13 +105,15 @@ async function main() {
105
105
  }
106
106
 
107
107
  try {
108
- const { RegistryUpdater } = require(path.resolve(REPO_ROOT, '.sinapse-ai/core/ids/registry-updater.js'));
109
- const updater = new RegistryUpdater();
110
- const result = await updater.processChanges(changes);
111
-
112
- if (result.updated > 0) {
113
- console.log(`[IDS-Hook] Registry synced: ${result.updated} entities updated before push.`);
114
- }
108
+ // Canonical deterministic generator (see ids-post-commit.js for why the
109
+ // incremental RegistryUpdater is NOT used: it emits a divergent schema that
110
+ // churned the whole registry). populate() is a fixed point.
111
+ const { populate } = require(
112
+ path.resolve(REPO_ROOT, '.sinapse-ai/development/scripts/populate-entity-registry.js'),
113
+ );
114
+ const registry = populate();
115
+ const count = registry && registry.metadata ? registry.metadata.entityCount : 0;
116
+ console.log(`[IDS-Hook] Registry synced before push (canonical, ${count} entities).`);
115
117
  } catch (err) {
116
118
  // Pre-push hook should warn but NOT block push
117
119
  console.warn(`[IDS-Hook] Registry sync failed (non-blocking): ${err.message}`);
@@ -39,15 +39,12 @@ function readStdin() {
39
39
  });
40
40
  }
41
41
 
42
+ // Story 10.47: delegate to the shared grounding config loader instead of
43
+ // duplicating the read+parse. The require is guarded so the hook stays
44
+ // fail-open even if the shared module is somehow absent at runtime.
42
45
  function loadConfig() {
43
46
  try {
44
- if (!fs.existsSync(CONFIG_PATH)) return null;
45
- const raw = fs.readFileSync(CONFIG_PATH, 'utf8');
46
- let yaml;
47
- try { yaml = require('js-yaml'); } catch { return null; }
48
- const parsed = yaml.load(raw);
49
- if (!parsed || typeof parsed !== 'object') return null;
50
- return parsed;
47
+ return require('../core/grounding/config-loader.cjs').loadGroundingConfig(CONFIG_PATH);
51
48
  } catch {
52
49
  return null;
53
50
  }
@@ -66,15 +66,12 @@ function readStdin() {
66
66
  });
67
67
  }
68
68
 
69
+ // Story 10.47: delegate to the shared grounding config loader instead of
70
+ // duplicating the read+parse. The require is guarded so the hook stays
71
+ // fail-open even if the shared module is somehow absent at runtime.
69
72
  function loadConfig() {
70
73
  try {
71
- if (!fs.existsSync(CONFIG_PATH)) return null;
72
- const raw = fs.readFileSync(CONFIG_PATH, 'utf8');
73
- let yaml;
74
- try { yaml = require('js-yaml'); } catch { return null; }
75
- const parsed = yaml.load(raw);
76
- if (!parsed || typeof parsed !== 'object') return null;
77
- return parsed;
74
+ return require('../core/grounding/config-loader.cjs').loadGroundingConfig(CONFIG_PATH);
78
75
  } catch {
79
76
  return null;
80
77
  }