sinapse-ai 1.8.0 → 1.9.1

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 (361) hide show
  1. package/.claude/hooks/mind-clone-governance.py +212 -212
  2. package/.claude/hooks/read-protection.py +152 -152
  3. package/.claude/hooks/slug-validation.py +175 -175
  4. package/.claude/hooks/sql-governance.py +183 -183
  5. package/.claude/rules/documentation-first.md +1 -1
  6. package/.claude/rules/hook-governance.md +1 -1
  7. package/.claude/rules/mandatory-delegation.md +1 -1
  8. package/.claude/rules/project-intelligence.md +1 -1
  9. package/.codex/agents/analyst.md +4 -371
  10. package/.codex/agents/animations-orqx.md +4 -57
  11. package/.codex/agents/architect.md +4 -560
  12. package/.codex/agents/brand-orqx.md +4 -95
  13. package/.codex/agents/claude-mastery-chief.md +4 -0
  14. package/.codex/agents/cloning-orqx.md +4 -70
  15. package/.codex/agents/commercial-orqx.md +4 -67
  16. package/.codex/agents/config-engineer.md +2 -2
  17. package/.codex/agents/content-orqx.md +4 -77
  18. package/.codex/agents/copy-orqx.md +4 -65
  19. package/.codex/agents/cost-optimizer.md +4 -0
  20. package/.codex/agents/council-orqx.md +4 -68
  21. package/.codex/agents/courses-orqx.md +4 -64
  22. package/.codex/agents/cro-persuasion.md +4 -0
  23. package/.codex/agents/cyber-orqx.md +4 -67
  24. package/.codex/agents/data-engineer.md +4 -542
  25. package/.codex/agents/design-orqx.md +4 -65
  26. package/.codex/agents/design-system.md +4 -210
  27. package/.codex/agents/developer.md +4 -666
  28. package/.codex/agents/devops.md +4 -668
  29. package/.codex/agents/finance-orqx.md +4 -57
  30. package/.codex/agents/fiscal-compliance-br.md +4 -0
  31. package/.codex/agents/forecast-strategist.md +4 -0
  32. package/.codex/agents/growth-orqx.md +4 -75
  33. package/.codex/agents/hooks-architect.md +2 -2
  34. package/.codex/agents/mcp-integrator.md +2 -2
  35. package/.codex/agents/paidmedia-orqx.md +4 -67
  36. package/.codex/agents/platform-aesthetic-director.md +4 -0
  37. package/.codex/agents/premium-packaging-strategist.md +4 -0
  38. package/.codex/agents/product-lead.md +4 -371
  39. package/.codex/agents/product-orqx.md +4 -57
  40. package/.codex/agents/product-surface-director.md +4 -0
  41. package/.codex/agents/project-integrator.md +2 -2
  42. package/.codex/agents/project-lead.md +4 -414
  43. package/.codex/agents/quality-gate.md +4 -547
  44. package/.codex/agents/research-orqx.md +4 -67
  45. package/.codex/agents/roadmap-sentinel.md +2 -2
  46. package/.codex/agents/skill-craftsman.md +2 -2
  47. package/.codex/agents/snps-orqx.md +4 -684
  48. package/.codex/agents/sop-extractor.md +4 -61
  49. package/.codex/agents/sprint-lead.md +4 -324
  50. package/.codex/agents/squad-creator.md +4 -402
  51. package/.codex/agents/storytelling-orqx.md +4 -65
  52. package/.codex/agents/swarm-orqx.md +4 -64
  53. package/.codex/agents/ux-design-expert.md +4 -532
  54. package/.codex/agents/ux-designer.md +4 -124
  55. package/.codex/command-registry.json +9 -9
  56. package/.codex/delegation-matrix.json +375 -839
  57. package/.codex/delegation-parity.json +658 -0
  58. package/.codex/handoff-packet.parity.schema.json +148 -0
  59. package/.codex/handoff-packet.template.json +26 -0
  60. package/.codex/instructions.md +8 -8
  61. package/.codex/scripts/resolve-codex-agent.js +482 -0
  62. package/.codex/scripts/resolve-codex-command.js +75 -12
  63. package/.codex/scripts/resolve-codex-delegation.js +131 -92
  64. package/.codex/skills/sinapse-claude/SKILL.md +3 -3
  65. package/.codex/skills/sinapse-po/SKILL.md +1 -1
  66. package/.codex/tasks/resolve-sinapse-conflict.md +1 -1
  67. package/.sinapse-ai/constitution.md +5 -5
  68. package/.sinapse-ai/core/doctor/checks/git-hooks.js +163 -19
  69. package/.sinapse-ai/core/events/dashboard-emitter.js +30 -9
  70. package/.sinapse-ai/core/execution/subagent-dispatcher.js +1 -1
  71. package/.sinapse-ai/core/synapse/engine.js +15 -0
  72. package/.sinapse-ai/core/ui/observability-panel.js +240 -0
  73. package/.sinapse-ai/core-config.yaml +0 -20
  74. package/.sinapse-ai/data/entity-registry.yaml +185 -236
  75. package/.sinapse-ai/development/agents/snps-orqx.md +16 -26
  76. package/.sinapse-ai/development/tasks/build-autonomous.md +11 -1
  77. package/.sinapse-ai/development/tasks/build-resume.md +8 -0
  78. package/.sinapse-ai/development/tasks/build-status.md +8 -0
  79. package/.sinapse-ai/development/tasks/build.md +8 -0
  80. package/.sinapse-ai/development/tasks/cleanup-worktrees.md +8 -1
  81. package/.sinapse-ai/development/tasks/gotcha.md +8 -0
  82. package/.sinapse-ai/development/tasks/gotchas.md +8 -0
  83. package/.sinapse-ai/development/tasks/ids-health.md +14 -6
  84. package/.sinapse-ai/development/tasks/list-mcps.md +15 -0
  85. package/.sinapse-ai/development/tasks/merge-worktree.md +8 -1
  86. package/.sinapse-ai/development/tasks/qa-review-build.md +18 -0
  87. package/.sinapse-ai/development/tasks/remove-mcp.md +8 -1
  88. package/.sinapse-ai/development/tasks/validate-agents.md +26 -14
  89. package/.sinapse-ai/development/templates/service-template/README.md.hbs +159 -159
  90. package/.sinapse-ai/development/templates/service-template/__tests__/index.test.ts.hbs +238 -238
  91. package/.sinapse-ai/development/templates/service-template/client.ts.hbs +404 -404
  92. package/.sinapse-ai/development/templates/service-template/errors.ts.hbs +183 -183
  93. package/.sinapse-ai/development/templates/service-template/index.ts.hbs +121 -121
  94. package/.sinapse-ai/development/templates/service-template/package.json.hbs +88 -88
  95. package/.sinapse-ai/development/templates/service-template/types.ts.hbs +146 -146
  96. package/.sinapse-ai/development/templates/squad-template/LICENSE +22 -22
  97. package/.sinapse-ai/git-hooks/lib/framework-guard.js +258 -0
  98. package/.sinapse-ai/git-hooks/lib/secret-scanner-core.js +355 -0
  99. package/.sinapse-ai/git-hooks/lib/staged-secret-scan.js +179 -0
  100. package/.sinapse-ai/git-hooks/lib/staged-sql-guard.js +204 -0
  101. package/.sinapse-ai/git-hooks/post-commit +28 -0
  102. package/.sinapse-ai/git-hooks/pre-commit +81 -0
  103. package/.sinapse-ai/git-hooks/pre-push +83 -0
  104. package/.sinapse-ai/hooks/ids-post-commit.js +13 -11
  105. package/.sinapse-ai/hooks/ids-pre-push.js +9 -7
  106. package/.sinapse-ai/infrastructure/scripts/codex-parity/resolve.js +161 -0
  107. package/.sinapse-ai/infrastructure/scripts/dashboard-status-writer.js +6 -2
  108. package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +65 -68
  109. package/.sinapse-ai/infrastructure/scripts/sync-codex-local-first.js +156 -1
  110. package/.sinapse-ai/infrastructure/scripts/validate-codex-delegation.js +1 -4
  111. package/.sinapse-ai/infrastructure/scripts/validate-codex-integration.js +41 -5
  112. package/.sinapse-ai/infrastructure/templates/coderabbit.yaml.template +280 -280
  113. package/.sinapse-ai/infrastructure/templates/config/env.example +16 -16
  114. package/.sinapse-ai/infrastructure/templates/config/gitignore-additions.tmpl +59 -59
  115. package/.sinapse-ai/infrastructure/templates/github/CODEOWNERS.template +12 -12
  116. package/.sinapse-ai/infrastructure/templates/github-workflows/ci.yml.template +170 -170
  117. package/.sinapse-ai/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -331
  118. package/.sinapse-ai/infrastructure/templates/github-workflows/release.yml.template +197 -197
  119. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +19 -19
  120. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -86
  121. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -146
  122. package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-sinapse-base.tmpl +64 -64
  123. package/.sinapse-ai/infrastructure/templates/safe-collab/CODEOWNERS.template +16 -16
  124. package/.sinapse-ai/infrastructure/templates/sinapse-sync.yaml.template +183 -183
  125. package/.sinapse-ai/install-manifest.yaml +112 -164
  126. package/.sinapse-ai/local-config.yaml.template +65 -65
  127. package/.sinapse-ai/product/templates/adr.hbs +126 -126
  128. package/.sinapse-ai/product/templates/dbdr.hbs +242 -242
  129. package/.sinapse-ai/product/templates/epic.hbs +213 -213
  130. package/.sinapse-ai/product/templates/ide-rules/codex-rules.md +30 -0
  131. package/.sinapse-ai/product/templates/pmdr.hbs +187 -187
  132. package/.sinapse-ai/product/templates/prd-v2.0.hbs +217 -217
  133. package/.sinapse-ai/product/templates/prd.hbs +202 -202
  134. package/.sinapse-ai/product/templates/statusline/statusline-script.js +31 -8
  135. package/.sinapse-ai/product/templates/statusline/track-agent-clear.cjs +79 -0
  136. package/.sinapse-ai/product/templates/statusline/track-agent.cjs +218 -0
  137. package/.sinapse-ai/product/templates/story.hbs +264 -264
  138. package/.sinapse-ai/product/templates/task.hbs +171 -171
  139. package/.sinapse-ai/product/templates/tmpl-comment-on-examples.sql +159 -159
  140. package/.sinapse-ai/product/templates/tmpl-migration-script.sql +92 -92
  141. package/.sinapse-ai/product/templates/tmpl-rls-granular-policies.sql +105 -105
  142. package/.sinapse-ai/product/templates/tmpl-rls-kiss-policy.sql +11 -11
  143. package/.sinapse-ai/product/templates/tmpl-rls-roles.sql +136 -136
  144. package/.sinapse-ai/product/templates/tmpl-rls-simple.sql +78 -78
  145. package/.sinapse-ai/product/templates/tmpl-rls-tenant.sql +153 -153
  146. package/.sinapse-ai/product/templates/tmpl-rollback-script.sql +78 -78
  147. package/.sinapse-ai/product/templates/tmpl-seed-data.sql +141 -141
  148. package/.sinapse-ai/product/templates/tmpl-smoke-test.sql +17 -17
  149. package/.sinapse-ai/product/templates/tmpl-staging-copy-merge.sql +140 -140
  150. package/.sinapse-ai/product/templates/tmpl-stored-proc.sql +141 -141
  151. package/.sinapse-ai/product/templates/tmpl-trigger.sql +153 -153
  152. package/.sinapse-ai/product/templates/tmpl-view-materialized.sql +134 -134
  153. package/.sinapse-ai/product/templates/tmpl-view.sql +178 -178
  154. package/AGENTS.md +193 -0
  155. package/CHANGELOG.md +1247 -0
  156. package/LICENSE +63 -63
  157. package/README.en.md +17 -18
  158. package/README.md +18 -19
  159. package/bin/cli.js +1 -1
  160. package/bin/commands/install.js +194 -22
  161. package/bin/commands/status.js +14 -1
  162. package/bin/commands/uninstall.js +2 -2
  163. package/bin/commands/update.js +52 -0
  164. package/bin/lib/setup-statusline.js +191 -0
  165. package/bin/sinapse-init.js +11 -83
  166. package/bin/utils/framework-guard.js +17 -4
  167. package/bin/utils/secret-scanner-core.js +109 -7
  168. package/bin/utils/staged-sql-guard.js +204 -0
  169. package/bin/utils/validate-publish.js +63 -0
  170. package/docs/agent-reference-guide.md +5 -7
  171. package/docs/framework/agent-prefix-convention.md +58 -0
  172. package/docs/framework/architecture-overview.md +4 -4
  173. package/docs/framework/collaboration-activation.md +45 -0
  174. package/docs/framework/guiding-principles.md +9 -9
  175. package/docs/getting-started.md +1 -1
  176. package/docs/guides/agent-reference.md +1 -1
  177. package/docs/guides/codex-config.md +4 -5
  178. package/docs/pt/architecture/sub-orqx-pattern.md +20 -18
  179. package/docs/security/overview.md +1 -1
  180. package/package.json +16 -12
  181. package/packages/installer/src/index.js +26 -0
  182. package/packages/installer/src/installer/git-hooks-installer.js +211 -47
  183. package/packages/installer/src/installer/sinapse-ai-installer.js +71 -0
  184. package/packages/installer/src/wizard/feedback.js +1 -1
  185. package/packages/installer/src/wizard/ide-config-generator.js +26 -26
  186. package/packages/installer/src/wizard/index.js +53 -4
  187. package/packages/sinapse-install/bin/edmcp.js +0 -0
  188. package/packages/sinapse-install/bin/sinapse-install.js +0 -0
  189. package/scripts/audit-tasks.cjs +112 -91
  190. package/scripts/check-markdown-links.py +352 -352
  191. package/scripts/prepare-hooks.js +58 -0
  192. package/scripts/regenerate-orqx-stubs.ps1 +2 -3
  193. package/scripts/sync-counts.js +10 -2
  194. package/scripts/sync-squad-yaml-components.js +108 -6
  195. package/scripts/validate-agents-md.js +128 -0
  196. package/scripts/validate-all.js +1 -0
  197. package/scripts/validate-squad-orqx.js +19 -9
  198. package/sinapse/agents/sinapse-orqx.md +16 -26
  199. package/sinapse/agents/snps-orqx.md +15 -25
  200. package/sinapse/knowledge-base/routing-catalog.md +1 -1
  201. package/sinapse/tasks/diagnose-and-route.md +1 -1
  202. package/sinapse/tasks/squad-status-report.md +1 -1
  203. package/squads/claude-code-mastery/agents/claude-mastery-chief.md +1 -1
  204. package/squads/claude-code-mastery/agents/hooks-architect.md +60 -68
  205. package/squads/claude-code-mastery/knowledge-base/swarm-orchestration-patterns.md +1 -1
  206. package/squads/claude-code-mastery/squad.yaml +8 -0
  207. package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
  208. package/squads/claude-code-mastery/workflows/optimization-cycle.yaml +4 -4
  209. package/squads/claude-code-mastery/workflows/project-setup-cycle.yaml +4 -4
  210. package/squads/squad-animations/README.md +1 -1
  211. package/squads/squad-animations/squad.yaml +1 -1
  212. package/squads/squad-brand/squad.yaml +1 -1
  213. package/squads/squad-cloning/README.md +1 -1
  214. package/squads/squad-cloning/squad.yaml +1 -1
  215. package/squads/squad-commercial/README.md +1 -1
  216. package/squads/squad-commercial/squad.yaml +2 -3
  217. package/squads/squad-content/README.md +1 -1
  218. package/squads/squad-content/squad.yaml +1 -1
  219. package/squads/squad-copy/README.md +1 -1
  220. package/squads/squad-copy/squad.yaml +2 -3
  221. package/squads/squad-council/README.md +1 -1
  222. package/squads/squad-courses/README.md +1 -1
  223. package/squads/squad-courses/squad.yaml +1 -1
  224. package/squads/squad-cybersecurity/README.md +1 -1
  225. package/squads/squad-cybersecurity/squad.yaml +2 -3
  226. package/squads/squad-design/README.md +1 -1
  227. package/squads/{squad-artdir → squad-design}/agents/cro-persuasion.md +1 -1
  228. package/squads/{squad-artdir → squad-design}/agents/platform-aesthetic-director.md +2 -2
  229. package/squads/{squad-artdir → squad-design}/agents/premium-packaging-strategist.md +2 -2
  230. package/squads/{squad-artdir → squad-design}/agents/product-surface-director.md +3 -3
  231. package/squads/squad-design/squad.yaml +6 -3
  232. package/squads/squad-finance/README.md +1 -1
  233. package/squads/squad-finance/squad.yaml +7 -1
  234. package/squads/squad-growth/README.md +1 -1
  235. package/squads/squad-growth/squad.yaml +1 -1
  236. package/squads/squad-paidmedia/README.md +1 -1
  237. package/squads/squad-paidmedia/squad.yaml +2 -3
  238. package/squads/squad-product/README.md +1 -1
  239. package/squads/squad-product/squad.yaml +1 -1
  240. package/squads/squad-research/README.md +1 -1
  241. package/squads/squad-research/squad.yaml +2 -3
  242. package/squads/squad-storytelling/README.md +1 -1
  243. package/squads/squad-storytelling/squad.yaml +2 -3
  244. package/.codex/agents/brad-frost.md +0 -46
  245. package/.codex/agents/claude-orqx.md +0 -72
  246. package/.codex/agents/copy-chief.md +0 -162
  247. package/.codex/agents/cyber-chief.md +0 -169
  248. package/.codex/agents/dan-mall.md +0 -43
  249. package/.codex/agents/data-chief.md +0 -198
  250. package/.codex/agents/dave-malouf.md +0 -43
  251. package/.codex/agents/db-sage.md +0 -152
  252. package/.codex/agents/design-chief.md +0 -226
  253. package/.codex/agents/dev.md +0 -102
  254. package/.codex/agents/legal-chief.md +0 -199
  255. package/.codex/agents/nano-banana-generator.md +0 -42
  256. package/.codex/agents/pm.md +0 -81
  257. package/.codex/agents/po.md +0 -85
  258. package/.codex/agents/qa.md +0 -98
  259. package/.codex/agents/sm.md +0 -77
  260. package/.codex/agents/squad-chief.md +0 -1553
  261. package/.codex/agents/squad.md +0 -66
  262. package/.codex/agents/story-chief.md +0 -180
  263. package/.codex/agents/tools-orqx.md +0 -219
  264. package/.codex/agents/traffic-masters-chief.md +0 -211
  265. package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +0 -265
  266. package/.sinapse-ai/core/permissions/__tests__/permission-mode.test.js +0 -293
  267. package/.sinapse-ai/data/registry-update-log.jsonl +0 -158
  268. package/.sinapse-ai/infrastructure/scripts/ide-sync/gemini-commands.js +0 -298
  269. package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/antigravity.js +0 -121
  270. package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/cursor.js +0 -119
  271. package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/github-copilot.js +0 -191
  272. package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/kimi.js +0 -448
  273. package/.sinapse-ai/infrastructure/tests/project-status-loader.test.js +0 -569
  274. package/.sinapse-ai/infrastructure/tests/regression-suite-v2.md +0 -622
  275. package/.sinapse-ai/infrastructure/tests/validate-module.js +0 -98
  276. package/.sinapse-ai/infrastructure/tests/worktree-manager.test.js +0 -620
  277. package/.sinapse-ai/monitor/hooks/lib/__init__.py +0 -2
  278. package/.sinapse-ai/monitor/hooks/lib/enrich.py +0 -59
  279. package/.sinapse-ai/monitor/hooks/lib/send_event.py +0 -48
  280. package/.sinapse-ai/monitor/hooks/notification.py +0 -30
  281. package/.sinapse-ai/monitor/hooks/post_tool_use.py +0 -46
  282. package/.sinapse-ai/monitor/hooks/pre_compact.py +0 -30
  283. package/.sinapse-ai/monitor/hooks/pre_tool_use.py +0 -41
  284. package/.sinapse-ai/monitor/hooks/stop.py +0 -30
  285. package/.sinapse-ai/monitor/hooks/subagent_stop.py +0 -30
  286. package/.sinapse-ai/monitor/hooks/user_prompt_submit.py +0 -39
  287. package/.sinapse-ai/product/templates/statusline/track-agent.sh +0 -69
  288. package/.sinapse-ai/workflow-intelligence/__tests__/confidence-scorer.test.js +0 -335
  289. package/.sinapse-ai/workflow-intelligence/__tests__/integration.test.js +0 -340
  290. package/.sinapse-ai/workflow-intelligence/__tests__/suggestion-engine.test.js +0 -438
  291. package/.sinapse-ai/workflow-intelligence/__tests__/wave-analyzer.test.js +0 -448
  292. package/.sinapse-ai/workflow-intelligence/__tests__/workflow-registry.test.js +0 -303
  293. package/bin/sinapse-graph.js +0 -19
  294. package/docs/codex-integration-process.md +0 -22
  295. package/docs/codex-parity-program.md +0 -27
  296. package/packages/installer/src/__tests__/performance-benchmark.js +0 -383
  297. package/packages/installer/tests/integration/environment-configuration.test.js +0 -332
  298. package/packages/installer/tests/integration/wizard-detection.test.js +0 -352
  299. package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +0 -383
  300. package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +0 -193
  301. package/packages/installer/tests/unit/config-validator.test.js +0 -315
  302. package/packages/installer/tests/unit/detection/detect-project-type.test.js +0 -539
  303. package/packages/installer/tests/unit/doctor/doctor-checks.test.js +0 -636
  304. package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +0 -192
  305. package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +0 -186
  306. package/packages/installer/tests/unit/env-template.test.js +0 -187
  307. package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +0 -310
  308. package/packages/installer/tests/unit/git-hooks-installer.test.js +0 -262
  309. package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +0 -231
  310. package/packages/installer/tests/unit/merger/env-merger.test.js +0 -191
  311. package/packages/installer/tests/unit/merger/markdown-merger.test.js +0 -262
  312. package/packages/installer/tests/unit/merger/strategies.test.js +0 -154
  313. package/packages/installer/tests/unit/merger/yaml-merger.test.js +0 -328
  314. package/packages/sinapse-install/tests/unit/chrome-brain.smoke.test.js +0 -66
  315. package/scripts/install-monitor-hooks.sh +0 -82
  316. package/squads/squad-artdir/README.md +0 -90
  317. package/squads/squad-artdir/agents/accessibility-guardian.md +0 -184
  318. package/squads/squad-artdir/agents/artdir-orqx.md +0 -222
  319. package/squads/squad-artdir/agents/color-psychologist.md +0 -166
  320. package/squads/squad-artdir/agents/design-system-architect.md +0 -100
  321. package/squads/squad-artdir/agents/ia-architect.md +0 -169
  322. package/squads/squad-artdir/agents/interaction-designer.md +0 -162
  323. package/squads/squad-artdir/agents/layout-engineer.md +0 -163
  324. package/squads/squad-artdir/agents/motion-architect.md +0 -185
  325. package/squads/squad-artdir/agents/type-systemist.md +0 -138
  326. package/squads/squad-artdir/agents/visual-strategist.md +0 -127
  327. package/squads/squad-artdir/checklists/seven-pillars-validation-checklist.md +0 -172
  328. package/squads/squad-artdir/knowledge-base/case-nyo-ia-reference.md +0 -289
  329. package/squads/squad-artdir/knowledge-base/deliverables-templates.md +0 -457
  330. package/squads/squad-artdir/knowledge-base/motion-technique-catalog.md +0 -247
  331. package/squads/squad-artdir/knowledge-base/premium-packaging-principles.md +0 -133
  332. package/squads/squad-artdir/knowledge-base/psychological-toolkit.md +0 -229
  333. package/squads/squad-artdir/knowledge-base/saas-art-direction-canon.md +0 -242
  334. package/squads/squad-artdir/knowledge-base/seven-pillars-framework.md +0 -289
  335. package/squads/squad-artdir/knowledge-base/ten-pillars-framework.md +0 -221
  336. package/squads/squad-artdir/package.json +0 -20
  337. package/squads/squad-artdir/squad.yaml +0 -299
  338. package/squads/squad-artdir/tasks/audit-conversion.md +0 -97
  339. package/squads/squad-artdir/tasks/audit-drift-multi-surface.md +0 -55
  340. package/squads/squad-artdir/tasks/consult-saas-canon.md +0 -54
  341. package/squads/squad-artdir/tasks/create-art-direction-brief.md +0 -110
  342. package/squads/squad-artdir/tasks/create-premium-packaging-brief.md +0 -61
  343. package/squads/squad-artdir/tasks/create-wireflow.md +0 -84
  344. package/squads/squad-artdir/tasks/design-color-system.md +0 -81
  345. package/squads/squad-artdir/tasks/design-product-surface.md +0 -60
  346. package/squads/squad-artdir/tasks/design-token-system.md +0 -58
  347. package/squads/squad-artdir/tasks/diagnose-visual-language.md +0 -92
  348. package/squads/squad-artdir/tasks/first-5-minutes-choreography.md +0 -65
  349. package/squads/squad-artdir/tasks/specify-motion-system.md +0 -84
  350. package/squads/squad-artdir/tasks/validate-against-pillars.md +0 -143
  351. package/squads/squad-artdir/templates/art-direction-brief-template.md +0 -215
  352. package/squads/squad-artdir/workflows/conversion-audit-cycle.yaml +0 -142
  353. package/squads/squad-artdir/workflows/full-art-direction-cycle.yaml +0 -179
  354. package/squads/squad-artdir/workflows/saas-platform-art-direction-cycle.yaml +0 -338
  355. package/squads/squad-commercial/agents/legal-chief.md +0 -199
  356. package/squads/squad-copy/agents/copy-chief.md +0 -162
  357. package/squads/squad-cybersecurity/agents/cyber-chief.md +0 -169
  358. package/squads/squad-design/agents/design-chief.md +0 -226
  359. package/squads/squad-paidmedia/agents/traffic-masters-chief.md +0 -211
  360. package/squads/squad-research/agents/data-chief.md +0 -198
  361. package/squads/squad-storytelling/agents/story-chief.md +0 -180
@@ -1,636 +0,0 @@
1
- /**
2
- * Unit Tests: Doctor Check Modules
3
- * Story INS-4.1: sinapse doctor rewrite
4
- * Story INS-4.8: 3 new checks (skills-count, commands-count, hooks-claude-count)
5
- *
6
- * Tests all 15 check modules individually with mocked filesystem.
7
- */
8
-
9
- const path = require('path');
10
- const fs = require('fs');
11
-
12
- // Mock fs for controlled test scenarios
13
- jest.mock('fs');
14
-
15
- const nodeVersionCheck = require('../../../../../.sinapse-ai/core/doctor/checks/node-version');
16
- const npmPackagesCheck = require('../../../../../.sinapse-ai/core/doctor/checks/npm-packages');
17
- const settingsJsonCheck = require('../../../../../.sinapse-ai/core/doctor/checks/settings-json');
18
- const rulesFilesCheck = require('../../../../../.sinapse-ai/core/doctor/checks/rules-files');
19
- const agentMemoryCheck = require('../../../../../.sinapse-ai/core/doctor/checks/agent-memory');
20
- const entityRegistryCheck = require('../../../../../.sinapse-ai/core/doctor/checks/entity-registry');
21
- const gitHooksCheck = require('../../../../../.sinapse-ai/core/doctor/checks/git-hooks');
22
- const coreConfigCheck = require('../../../../../.sinapse-ai/core/doctor/checks/core-config');
23
- const claudeMdCheck = require('../../../../../.sinapse-ai/core/doctor/checks/claude-md');
24
- const graphDashboardCheck = require('../../../../../.sinapse-ai/core/doctor/checks/graph-dashboard');
25
- const codeIntelCheck = require('../../../../../.sinapse-ai/core/doctor/checks/code-intel');
26
- const ideSyncCheck = require('../../../../../.sinapse-ai/core/doctor/checks/ide-sync');
27
- const skillsCountCheck = require('../../../../../.sinapse-ai/core/doctor/checks/skills-count');
28
- const commandsCountCheck = require('../../../../../.sinapse-ai/core/doctor/checks/commands-count');
29
- const hooksClaudeCountCheck = require('../../../../../.sinapse-ai/core/doctor/checks/hooks-claude-count');
30
- const { loadChecks } = require('../../../../../.sinapse-ai/core/doctor/checks');
31
-
32
- const mockContext = {
33
- projectRoot: '/mock/project',
34
- frameworkRoot: '/mock/framework',
35
- options: { fix: false, json: false, dryRun: false, quiet: false },
36
- };
37
-
38
- beforeEach(() => {
39
- jest.clearAllMocks();
40
- });
41
-
42
- describe('node-version check', () => {
43
- it('should PASS for current Node.js version (>=18)', async () => {
44
- const result = await nodeVersionCheck.run(mockContext);
45
- expect(result.check).toBe('node-version');
46
- expect(result.status).toBe('PASS');
47
- expect(result.message).toContain('Node.js');
48
- });
49
- });
50
-
51
- describe('npm-packages check', () => {
52
- // Story 10.48 + v1.4.2: this check no longer treats a missing project-level
53
- // node_modules/ as a blocker. It validates that the deps DECLARED in
54
- // .sinapse-ai/package.json are *resolvable* via Node's resolver (which walks
55
- // parent + global node_modules). PASS unless a declared dep is unresolvable.
56
-
57
- it('should PASS when .sinapse-ai package has zero declared deps', async () => {
58
- // existsSync true everywhere → .sinapse-ai/package.json + node_modules present.
59
- // readFileSync auto-mock returns undefined → JSON.parse throws → caught →
60
- // falls through to PASS with totalDeps=0 and node_modules present.
61
- fs.existsSync.mockReturnValue(true);
62
- const result = await npmPackagesCheck.run(mockContext);
63
- expect(result.status).toBe('PASS');
64
- expect(result.message).toContain('.sinapse-ai deps complete');
65
- });
66
-
67
- it('should PASS (not FAIL) when there is no .sinapse-ai/package.json', async () => {
68
- fs.existsSync.mockReturnValue(false);
69
- const result = await npmPackagesCheck.run(mockContext);
70
- expect(result.status).toBe('PASS');
71
- expect(result.message).toContain('no .sinapse-ai/package.json');
72
- expect(result.fixCommand).toBeNull();
73
- });
74
-
75
- it('should FAIL when a declared .sinapse-ai dep is unresolvable', async () => {
76
- // .sinapse-ai/package.json present, declaring a dep that cannot resolve.
77
- fs.existsSync.mockImplementation((p) =>
78
- String(p).includes('package.json'),
79
- );
80
- fs.readFileSync.mockReturnValue(
81
- JSON.stringify({ dependencies: { '@sinapse/definitely-not-installed-xyz': '^1.0.0' } }),
82
- );
83
- const result = await npmPackagesCheck.run(mockContext);
84
- expect(result.status).toBe('FAIL');
85
- expect(result.message).toContain('unresolvable');
86
- expect(result.fixCommand).toBe('cd .sinapse-ai && npm install --production');
87
- });
88
- });
89
-
90
- describe('settings-json check', () => {
91
- it('should PASS with valid settings and sufficient deny rules', async () => {
92
- fs.existsSync.mockReturnValue(true);
93
- const mockSettings = {
94
- permissions: {
95
- deny: new Array(50).fill('Edit(.sinapse-ai/core/)'),
96
- allow: ['Edit(docs/)'],
97
- },
98
- };
99
- const coreConfig = 'boundary:\n protected:\n - .sinapse-ai/core/**\n exceptions:\n - agents/MEMORY.md';
100
- fs.readFileSync.mockImplementation((p) => {
101
- if (p.includes('settings.json')) return JSON.stringify(mockSettings);
102
- if (p.includes('core-config')) return coreConfig;
103
- return '';
104
- });
105
-
106
- const result = await settingsJsonCheck.run(mockContext);
107
- expect(result.status).toBe('PASS');
108
- expect(result.message).toContain('50 rules');
109
- });
110
-
111
- it('should FAIL when settings.json not found', async () => {
112
- fs.existsSync.mockReturnValue(false);
113
- const result = await settingsJsonCheck.run(mockContext);
114
- expect(result.status).toBe('FAIL');
115
- });
116
-
117
- it('should WARN when deny rules below threshold', async () => {
118
- fs.existsSync.mockReturnValue(true);
119
- const mockSettings = { permissions: { deny: ['one'], allow: [] } };
120
- fs.readFileSync.mockReturnValue(JSON.stringify(mockSettings));
121
-
122
- const result = await settingsJsonCheck.run(mockContext);
123
- expect(result.status).toBe('WARN');
124
- });
125
-
126
- it('should WARN when boundary paths not covered by deny rules', async () => {
127
- fs.existsSync.mockReturnValue(true);
128
- const mockSettings = {
129
- permissions: {
130
- deny: new Array(50).fill('Edit(docs/)'),
131
- allow: [],
132
- },
133
- };
134
- const coreConfig = 'boundary:\n protected:\n - .sinapse-ai/core/**\n - bin/sinapse.js\n exceptions:\n - test';
135
- fs.readFileSync.mockImplementation((p) => {
136
- if (p.includes('settings.json')) return JSON.stringify(mockSettings);
137
- if (p.includes('core-config')) return coreConfig;
138
- return '';
139
- });
140
-
141
- const result = await settingsJsonCheck.run(mockContext);
142
- expect(result.status).toBe('WARN');
143
- expect(result.message).toContain('boundary coverage');
144
- });
145
- });
146
-
147
- describe('rules-files check', () => {
148
- it('should PASS when all 7 rules files exist', async () => {
149
- fs.existsSync.mockReturnValue(true);
150
- const result = await rulesFilesCheck.run(mockContext);
151
- expect(result.status).toBe('PASS');
152
- expect(result.message).toContain('7');
153
- });
154
-
155
- it('should FAIL when rules directory missing', async () => {
156
- fs.existsSync.mockReturnValue(false);
157
- const result = await rulesFilesCheck.run(mockContext);
158
- expect(result.status).toBe('FAIL');
159
- });
160
-
161
- it('should WARN when some rules missing', async () => {
162
- fs.existsSync.mockImplementation((p) => {
163
- // Directory exists
164
- if (p.endsWith('rules')) return true;
165
- // Most files exist except 2
166
- if (p.includes('agent-authority') || p.includes('workflow-execution')) return false;
167
- return true;
168
- });
169
-
170
- const result = await rulesFilesCheck.run(mockContext);
171
- expect(result.status).toBe('WARN');
172
- expect(result.message).toContain('Missing 2');
173
- });
174
- });
175
-
176
- describe('agent-memory check', () => {
177
- it('should PASS when all 10 MEMORY.md files exist', async () => {
178
- fs.existsSync.mockReturnValue(true);
179
- const result = await agentMemoryCheck.run(mockContext);
180
- expect(result.status).toBe('PASS');
181
- expect(result.message).toContain('10/10');
182
- });
183
-
184
- it('should WARN when some MEMORY.md files missing', async () => {
185
- fs.existsSync.mockImplementation((p) => {
186
- if (p.endsWith('agents')) return true;
187
- if (p.includes('analyst') || p.includes('ux')) return false;
188
- return true;
189
- });
190
-
191
- const result = await agentMemoryCheck.run(mockContext);
192
- expect(result.status).toBe('WARN');
193
- expect(result.message).toContain('8/10');
194
- });
195
- });
196
-
197
- describe('entity-registry check', () => {
198
- it('should PASS when registry exists and is fresh', async () => {
199
- fs.existsSync.mockReturnValue(true);
200
- fs.statSync.mockReturnValue({ mtimeMs: Date.now() - 1000 });
201
- fs.readFileSync.mockReturnValue('line1\nline2\nline3');
202
-
203
- const result = await entityRegistryCheck.run(mockContext);
204
- expect(result.status).toBe('PASS');
205
- });
206
-
207
- it('should FAIL when registry not found', async () => {
208
- fs.existsSync.mockReturnValue(false);
209
- const result = await entityRegistryCheck.run(mockContext);
210
- expect(result.status).toBe('FAIL');
211
- });
212
-
213
- it('should WARN when registry is stale (>48h)', async () => {
214
- fs.existsSync.mockReturnValue(true);
215
- fs.statSync.mockReturnValue({ mtimeMs: Date.now() - 72 * 60 * 60 * 1000 });
216
- fs.readFileSync.mockReturnValue('line1\nline2');
217
-
218
- const result = await entityRegistryCheck.run(mockContext);
219
- expect(result.status).toBe('WARN');
220
- expect(result.message).toContain('72h');
221
- });
222
- });
223
-
224
- describe('git-hooks check', () => {
225
- it('should PASS when both hooks exist', async () => {
226
- fs.existsSync.mockReturnValue(true);
227
- const result = await gitHooksCheck.run(mockContext);
228
- expect(result.status).toBe('PASS');
229
- });
230
-
231
- it('should WARN when .husky directory missing', async () => {
232
- fs.existsSync.mockReturnValue(false);
233
- const result = await gitHooksCheck.run(mockContext);
234
- expect(result.status).toBe('WARN');
235
- });
236
- });
237
-
238
- describe('core-config check', () => {
239
- it('should PASS when config has all required sections', async () => {
240
- fs.existsSync.mockReturnValue(true);
241
- fs.readFileSync.mockReturnValue('boundary:\n test: true\nproject:\n name: test\nide:\n sync: true');
242
-
243
- const result = await coreConfigCheck.run(mockContext);
244
- expect(result.status).toBe('PASS');
245
- });
246
-
247
- it('should FAIL when config missing', async () => {
248
- fs.existsSync.mockReturnValue(false);
249
- const result = await coreConfigCheck.run(mockContext);
250
- expect(result.status).toBe('FAIL');
251
- });
252
-
253
- it('should FAIL when missing required sections', async () => {
254
- fs.existsSync.mockReturnValue(true);
255
- fs.readFileSync.mockReturnValue('project:\n name: test');
256
-
257
- const result = await coreConfigCheck.run(mockContext);
258
- expect(result.status).toBe('FAIL');
259
- expect(result.message).toContain('boundary');
260
- });
261
- });
262
-
263
- describe('claude-md check', () => {
264
- it('should PASS when all sections present', async () => {
265
- fs.existsSync.mockReturnValue(true);
266
- fs.readFileSync.mockReturnValue(
267
- '## Constitution\n## Framework vs Project Boundary\n## Sistema de Agentes',
268
- );
269
-
270
- const result = await claudeMdCheck.run(mockContext);
271
- expect(result.status).toBe('PASS');
272
- });
273
-
274
- it('should WARN when sections missing', async () => {
275
- fs.existsSync.mockReturnValue(true);
276
- fs.readFileSync.mockReturnValue('## Constitution\nSome content');
277
-
278
- const result = await claudeMdCheck.run(mockContext);
279
- expect(result.status).toBe('WARN');
280
- expect(result.message).toContain('Missing sections');
281
- });
282
- });
283
-
284
- describe('graph-dashboard check', () => {
285
- it('should PASS when directory has .js files', async () => {
286
- fs.existsSync.mockReturnValue(true);
287
- fs.readdirSync.mockReturnValue(['index.js', 'cli.js']);
288
-
289
- const result = await graphDashboardCheck.run(mockContext);
290
- expect(result.status).toBe('PASS');
291
- });
292
-
293
- it('should WARN when directory missing', async () => {
294
- fs.existsSync.mockReturnValue(false);
295
- const result = await graphDashboardCheck.run(mockContext);
296
- expect(result.status).toBe('WARN');
297
- });
298
- });
299
-
300
- describe('code-intel check', () => {
301
- // The code-intel check does a real require() of index.js and triggers
302
- // provider auto-detection. Tests that need provider detection must use
303
- // the real projectRoot and real fs (jest.requireActual).
304
- const realFs = jest.requireActual('fs');
305
- const realProjectRoot = path.join(__dirname, '..', '..', '..', '..', '..');
306
-
307
- it('should return INFO when code-intel dir does not exist', async () => {
308
- fs.existsSync.mockReturnValue(false);
309
- const result = await codeIntelCheck.run(mockContext);
310
- expect(result.status).toBe('INFO');
311
- });
312
-
313
- it('should WARN when index.js missing but dir exists', async () => {
314
- fs.existsSync.mockImplementation((p) => {
315
- // Dir exists, but index.js does not
316
- if (p.includes('index.js')) return false;
317
- return true;
318
- });
319
- const result = await codeIntelCheck.run(mockContext);
320
- expect(result.status).toBe('WARN');
321
- expect(result.message).toContain('index.js not found');
322
- });
323
-
324
- it('should PASS with RegistryProvider when entity-registry exists', async () => {
325
- // Use real fs + real project root so require() resolves the actual module
326
- // and RegistryProvider can load the real entity-registry.yaml
327
- const realContext = {
328
- ...mockContext,
329
- projectRoot: realProjectRoot,
330
- };
331
-
332
- // Temporarily restore real fs for this test
333
- fs.existsSync.mockImplementation(realFs.existsSync);
334
- fs.readFileSync.mockImplementation(realFs.readFileSync);
335
- fs.statSync.mockImplementation(realFs.statSync);
336
-
337
- // Only run if entity-registry actually exists (skip in CI without registry)
338
- const registryPath = path.join(realProjectRoot, '.sinapse-ai', 'data', 'entity-registry.yaml');
339
- if (!realFs.existsSync(registryPath)) {
340
- return; // skip — no registry available
341
- }
342
-
343
- const result = await codeIntelCheck.run(realContext);
344
- expect(result.status).toBe('PASS');
345
- expect(result.message).toContain('RegistryProvider');
346
- });
347
-
348
- it('should WARN when provider detection fails (no valid registry)', async () => {
349
- // Use real project root so require() works, but mock registry as empty
350
- const realContext = {
351
- ...mockContext,
352
- projectRoot: realProjectRoot,
353
- };
354
-
355
- // Real existsSync for module resolution, mocked readFileSync for empty registry
356
- fs.existsSync.mockImplementation((p) => {
357
- if (p.includes('entity-registry.yaml')) return true;
358
- return realFs.existsSync(p);
359
- });
360
- fs.statSync.mockImplementation((p) => {
361
- if (p.includes('entity-registry.yaml')) return { mtimeMs: Date.now(), size: 10 };
362
- return realFs.statSync(p);
363
- });
364
- fs.readFileSync.mockImplementation((p, enc) => {
365
- if (typeof p === 'string' && p.includes('entity-registry.yaml')) {
366
- return 'metadata:\n entityCount: 0';
367
- }
368
- return realFs.readFileSync(p, enc);
369
- });
370
-
371
- const result = await codeIntelCheck.run(realContext);
372
- // Without valid entities, provider won't be available → WARN or INFO
373
- expect(['WARN', 'INFO']).toContain(result.status);
374
- });
375
- });
376
-
377
- describe('ide-sync check', () => {
378
- it('should PASS when counts match', async () => {
379
- fs.existsSync.mockReturnValue(true);
380
- fs.readdirSync.mockImplementation((p) => {
381
- if (p.includes('commands')) return ['dev.md', 'qa.md'];
382
- return ['dev.md', 'qa.md'];
383
- });
384
-
385
- const result = await ideSyncCheck.run(mockContext);
386
- expect(result.status).toBe('PASS');
387
- });
388
-
389
- it('should WARN when IDE has fewer agents than expected (Audit 1 P1 DOC-1)', async () => {
390
- // Post-DOC-1 fix: WARN fires when IDE count < (framework + squad orqx).
391
- // Source dir has 5 framework agents; IDE has only 2 (missing 3 expected).
392
- fs.existsSync.mockReturnValue(true);
393
- fs.readdirSync.mockImplementation((p) => {
394
- if (p.includes('commands')) return ['dev.md', 'qa.md']; // 2 in IDE
395
- // Source agents dir — 5 framework agents (>= IDE count → expected gap)
396
- return ['dev.md', 'qa.md', 'pm.md', 'po.md', 'sm.md'];
397
- });
398
-
399
- const result = await ideSyncCheck.run(mockContext);
400
- expect(result.status).toBe('WARN');
401
- });
402
- });
403
-
404
- // === INS-4.8: New checks ===
405
-
406
- describe('skills-count check', () => {
407
- // v1.4.2: .claude/skills/ is an OPTIONAL user-installed area, not shipped by
408
- // `npx sinapse-ai install`. The check never FAILs: it PASSes proportional to
409
- // however many skills the user installed (>=1), and reports INFO when the
410
- // directory is absent or empty.
411
-
412
- it('should PASS when skill directories with SKILL.md exist', async () => {
413
- fs.existsSync.mockReturnValue(true);
414
- const dirs = Array.from({ length: 8 }, (_, i) => ({
415
- name: `skill-${i}`,
416
- isDirectory: () => true,
417
- isFile: () => false,
418
- }));
419
- fs.readdirSync.mockReturnValue(dirs);
420
-
421
- const result = await skillsCountCheck.run(mockContext);
422
- expect(result.check).toBe('skills-count');
423
- expect(result.status).toBe('PASS');
424
- expect(result.message).toContain('8');
425
- });
426
-
427
- it('should PASS even with a small number of installed skills', async () => {
428
- fs.existsSync.mockReturnValue(true);
429
- const dirs = Array.from({ length: 3 }, (_, i) => ({
430
- name: `skill-${i}`,
431
- isDirectory: () => true,
432
- isFile: () => false,
433
- }));
434
- fs.readdirSync.mockReturnValue(dirs);
435
-
436
- const result = await skillsCountCheck.run(mockContext);
437
- expect(result.status).toBe('PASS');
438
- expect(result.message).toContain('3');
439
- });
440
-
441
- it('should report INFO (not FAIL) when 0 skills found', async () => {
442
- // skills dir exists, but no subdir has a SKILL.md → count 0.
443
- fs.existsSync.mockImplementation((p) => !String(p).includes('SKILL.md'));
444
- const dirs = [{ name: 'empty', isDirectory: () => true, isFile: () => false }];
445
- fs.readdirSync.mockReturnValue(dirs);
446
-
447
- const result = await skillsCountCheck.run(mockContext);
448
- expect(result.status).toBe('INFO');
449
- expect(result.fixCommand).toBeNull();
450
- });
451
-
452
- it('should report INFO (not FAIL) when skills directory missing', async () => {
453
- fs.existsSync.mockReturnValue(false);
454
- const result = await skillsCountCheck.run(mockContext);
455
- expect(result.status).toBe('INFO');
456
- });
457
- });
458
-
459
- describe('commands-count check', () => {
460
- it('should PASS when >=20 command files', async () => {
461
- fs.existsSync.mockReturnValue(true);
462
- const files = Array.from({ length: 22 }, (_, i) => ({
463
- name: `cmd-${i}.md`,
464
- isDirectory: () => false,
465
- isFile: () => true,
466
- }));
467
- fs.readdirSync.mockReturnValue(files);
468
-
469
- const result = await commandsCountCheck.run(mockContext);
470
- expect(result.check).toBe('commands-count');
471
- expect(result.status).toBe('PASS');
472
- expect(result.message).toContain('22');
473
- });
474
-
475
- it('should WARN when 12-19 command files', async () => {
476
- fs.existsSync.mockReturnValue(true);
477
- const files = Array.from({ length: 15 }, (_, i) => ({
478
- name: `cmd-${i}.md`,
479
- isDirectory: () => false,
480
- isFile: () => true,
481
- }));
482
- fs.readdirSync.mockReturnValue(files);
483
-
484
- const result = await commandsCountCheck.run(mockContext);
485
- expect(result.status).toBe('WARN');
486
- expect(result.message).toContain('15/20');
487
- });
488
-
489
- it('should FAIL when <12 command files', async () => {
490
- fs.existsSync.mockReturnValue(true);
491
- const files = Array.from({ length: 5 }, (_, i) => ({
492
- name: `cmd-${i}.md`,
493
- isDirectory: () => false,
494
- isFile: () => true,
495
- }));
496
- fs.readdirSync.mockReturnValue(files);
497
-
498
- const result = await commandsCountCheck.run(mockContext);
499
- expect(result.status).toBe('FAIL');
500
- expect(result.message).toContain('5');
501
- });
502
-
503
- it('should FAIL when commands directory missing', async () => {
504
- fs.existsSync.mockReturnValue(false);
505
- const result = await commandsCountCheck.run(mockContext);
506
- expect(result.status).toBe('FAIL');
507
- });
508
- });
509
-
510
- describe('hooks-claude-count check', () => {
511
- it('should PASS when >=2 hook files and registered', async () => {
512
- fs.existsSync.mockReturnValue(true);
513
- const hookFiles = [
514
- { name: 'enforce-git-push.cjs', isFile: () => true, isDirectory: () => false },
515
- { name: 'pre-commit-check.cjs', isFile: () => true, isDirectory: () => false },
516
- ];
517
- fs.readdirSync.mockReturnValue(hookFiles);
518
- const settingsLocal = {
519
- hooks: {
520
- PreToolUse: [{ command: 'node .claude/hooks/enforce-git-push.cjs' }],
521
- PostToolUse: [{ command: 'node .claude/hooks/pre-commit-check.cjs' }],
522
- },
523
- };
524
- fs.readFileSync.mockReturnValue(JSON.stringify(settingsLocal));
525
-
526
- const result = await hooksClaudeCountCheck.run(mockContext);
527
- expect(result.check).toBe('hooks-claude-count');
528
- expect(result.status).toBe('PASS');
529
- expect(result.message).toContain('2');
530
- });
531
-
532
- it('should WARN when hooks present but not registered', async () => {
533
- fs.existsSync.mockImplementation((p) => {
534
- if (p.includes('settings.local.json')) return true;
535
- return true;
536
- });
537
- const hookFiles = [
538
- { name: 'hook-a.cjs', isFile: () => true, isDirectory: () => false },
539
- { name: 'hook-b.cjs', isFile: () => true, isDirectory: () => false },
540
- ];
541
- fs.readdirSync.mockReturnValue(hookFiles);
542
- fs.readFileSync.mockReturnValue(JSON.stringify({ hooks: {} }));
543
-
544
- const result = await hooksClaudeCountCheck.run(mockContext);
545
- expect(result.status).toBe('WARN');
546
- expect(result.message).toContain('not registered');
547
- });
548
-
549
- it('should WARN when <2 hook files', async () => {
550
- fs.existsSync.mockReturnValue(true);
551
- const hookFiles = [
552
- { name: 'single-hook.cjs', isFile: () => true, isDirectory: () => false },
553
- ];
554
- fs.readdirSync.mockReturnValue(hookFiles);
555
- fs.readFileSync.mockReturnValue(JSON.stringify({ hooks: {} }));
556
-
557
- const result = await hooksClaudeCountCheck.run(mockContext);
558
- expect(result.status).toBe('WARN');
559
- expect(result.message).toContain('1/2');
560
- });
561
-
562
- it('should FAIL when no hook files found', async () => {
563
- fs.existsSync.mockReturnValue(true);
564
- fs.readdirSync.mockReturnValue([]);
565
-
566
- const result = await hooksClaudeCountCheck.run(mockContext);
567
- expect(result.status).toBe('FAIL');
568
- });
569
-
570
- it('should FAIL when hooks directory missing', async () => {
571
- fs.existsSync.mockReturnValue(false);
572
- const result = await hooksClaudeCountCheck.run(mockContext);
573
- expect(result.status).toBe('FAIL');
574
- });
575
- });
576
-
577
- // === INS-4.8: Registry and task validation ===
578
-
579
- describe('check registry (INS-4.8)', () => {
580
- it('should load 15 checks total', () => {
581
- // loadChecks is the real function (not mocked) — verifies registration
582
- const checks = loadChecks();
583
- expect(checks).toHaveLength(16);
584
- });
585
-
586
- it('should include all 3 new checks', () => {
587
- const checks = loadChecks();
588
- const names = checks.map((c) => c.name);
589
- expect(names).toContain('skills-count');
590
- expect(names).toContain('commands-count');
591
- expect(names).toContain('hooks-claude-count');
592
- });
593
- });
594
-
595
- describe('health-check.yaml task (INS-4.8)', () => {
596
- it('should NOT have *doctor alias', () => {
597
- const realFs = jest.requireActual('fs');
598
- const yaml = realFs.readFileSync(
599
- path.join(__dirname, '..', '..', '..', '..', '..', '.sinapse-ai', 'development', 'tasks', 'health-check.yaml'),
600
- 'utf8',
601
- );
602
- // Verify *doctor is not in the aliases list (only *hc should be)
603
- const aliasMatch = yaml.match(/aliases:\s*\n((?:\s+-\s+.*\n)*)/);
604
- expect(aliasMatch).toBeTruthy();
605
- expect(aliasMatch[1]).not.toContain('*doctor');
606
- expect(aliasMatch[1]).toContain('*hc');
607
- });
608
-
609
- it('should reference sinapse doctor --json in instructions', () => {
610
- const realFs = jest.requireActual('fs');
611
- const yaml = realFs.readFileSync(
612
- path.join(__dirname, '..', '..', '..', '..', '..', '.sinapse-ai', 'development', 'tasks', 'health-check.yaml'),
613
- 'utf8',
614
- );
615
- expect(yaml).toContain('sinapse doctor --json');
616
- expect(yaml).toContain('npx sinapse-ai doctor --json');
617
- });
618
-
619
- it('should have governance_map with all 15 checks', () => {
620
- const realFs = jest.requireActual('fs');
621
- const yaml = realFs.readFileSync(
622
- path.join(__dirname, '..', '..', '..', '..', '..', '.sinapse-ai', 'development', 'tasks', 'health-check.yaml'),
623
- 'utf8',
624
- );
625
- const expectedChecks = [
626
- 'settings-json', 'rules-files', 'agent-memory', 'entity-registry',
627
- 'git-hooks', 'core-config', 'claude-md', 'ide-sync', 'graph-dashboard',
628
- 'code-intel', 'node-version', 'npm-packages', 'skills-count',
629
- 'commands-count', 'hooks-claude-count',
630
- ];
631
- for (const check of expectedChecks) {
632
- expect(yaml).toContain(`${check}:`);
633
- }
634
- });
635
- });
636
-