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,192 +0,0 @@
1
- /**
2
- * Unit Tests: Doctor Orchestrator
3
- * Story INS-4.1: sinapse doctor rewrite
4
- *
5
- * Tests for options forwarding, output format, and fix/dry-run behavior.
6
- */
7
-
8
- const fs = require('fs');
9
- const os = require('os');
10
- const path = require('path');
11
-
12
- // Use real modules for orchestrator testing (checks will hit real filesystem)
13
- const { runDoctorChecks, DOCTOR_VERSION, resolveExitCode } = require('../../../../../.sinapse-ai/core/doctor');
14
-
15
- const projectRoot = path.resolve(__dirname, '..', '..', '..', '..', '..');
16
-
17
- describe('Doctor Orchestrator', () => {
18
- describe('version', () => {
19
- it('should export DOCTOR_VERSION as semver string (Story A.3 bumped to 2.1.0)', () => {
20
- expect(DOCTOR_VERSION).toBe('2.1.0');
21
- });
22
- });
23
-
24
- describe('options forwarding (AC1)', () => {
25
- it('should accept and use options object', async () => {
26
- const result = await runDoctorChecks({ projectRoot });
27
- expect(result).toHaveProperty('formatted');
28
- expect(result).toHaveProperty('data');
29
- expect(result.data).toHaveProperty('version', '2.1.0');
30
- expect(result.data).toHaveProperty('summary');
31
- expect(result.data).toHaveProperty('checks');
32
- });
33
-
34
- it('should produce JSON when json option is true', async () => {
35
- const result = await runDoctorChecks({ json: true, projectRoot });
36
- expect(result.formatted).toBeTruthy();
37
-
38
- // Should be valid JSON
39
- const parsed = JSON.parse(result.formatted);
40
- expect(parsed).toHaveProperty('version');
41
- expect(parsed).toHaveProperty('summary');
42
- expect(parsed).toHaveProperty('checks');
43
- });
44
-
45
- it('should produce text when json option is false', async () => {
46
- const result = await runDoctorChecks({ json: false, projectRoot });
47
- expect(result.formatted).toContain('SINAPSE Doctor');
48
- expect(result.formatted).toContain('Summary:');
49
- });
50
- });
51
-
52
- describe('15 checks (AC2 + INS-4.8)', () => {
53
- it('should run exactly 15 checks', async () => {
54
- const result = await runDoctorChecks({ projectRoot });
55
- expect(result.data.checks).toHaveLength(16);
56
- });
57
-
58
- it('should return valid status for each check', async () => {
59
- const result = await runDoctorChecks({ projectRoot });
60
- const validStatuses = ['PASS', 'WARN', 'FAIL', 'INFO'];
61
-
62
- for (const check of result.data.checks) {
63
- expect(validStatuses).toContain(check.status);
64
- expect(check).toHaveProperty('check');
65
- expect(check).toHaveProperty('message');
66
- }
67
- });
68
-
69
- it('should include all expected check names', async () => {
70
- const result = await runDoctorChecks({ projectRoot });
71
- const checkNames = result.data.checks.map((c) => c.check);
72
-
73
- expect(checkNames).toContain('settings-json');
74
- expect(checkNames).toContain('rules-files');
75
- expect(checkNames).toContain('agent-memory');
76
- expect(checkNames).toContain('entity-registry');
77
- expect(checkNames).toContain('git-hooks');
78
- expect(checkNames).toContain('core-config');
79
- expect(checkNames).toContain('claude-md');
80
- expect(checkNames).toContain('ide-sync');
81
- expect(checkNames).toContain('graph-dashboard');
82
- expect(checkNames).toContain('code-intel');
83
- expect(checkNames).toContain('node-version');
84
- expect(checkNames).toContain('npm-packages');
85
- expect(checkNames).toContain('skills-count');
86
- expect(checkNames).toContain('commands-count');
87
- expect(checkNames).toContain('hooks-claude-count');
88
- expect(checkNames).toContain('manifest-version-parity');
89
- });
90
- });
91
-
92
- describe('summary (AC3)', () => {
93
- it('should have pass/warn/fail/info counts that sum to 15', async () => {
94
- const result = await runDoctorChecks({ projectRoot });
95
- const { pass, warn, fail, info } = result.data.summary;
96
- expect(pass + warn + fail + info).toBe(16);
97
- });
98
-
99
- it('should include Summary line in text output', async () => {
100
- const result = await runDoctorChecks({ projectRoot });
101
- expect(result.formatted).toMatch(/Summary: \d+ PASS \| \d+ WARN \| \d+ FAIL \| \d+ INFO/);
102
- });
103
- });
104
-
105
- describe('--dry-run (AC4)', () => {
106
- it('should include fixResults when dryRun is true', async () => {
107
- const result = await runDoctorChecks({ dryRun: true, projectRoot });
108
- expect(result.data).toHaveProperty('fixResults');
109
- });
110
-
111
- it('should not produce file changes with dryRun', async () => {
112
- const result = await runDoctorChecks({ dryRun: true, projectRoot });
113
- if (result.data.fixResults) {
114
- for (const fr of result.data.fixResults) {
115
- expect(fr.applied).toBe(false);
116
- }
117
- }
118
- });
119
- });
120
-
121
- describe('NOT_INSTALLED short-circuit (Story 10.42)', () => {
122
- let tempDir;
123
- let fakeHome;
124
-
125
- beforeEach(() => {
126
- // Isolated projectRoot + fake HOME so the doctor cannot see the
127
- // developer's real ~/.sinapse or ~/.claude. Passing homeDir via
128
- // options is the reliable way across POSIX and Windows (os.homedir
129
- // sometimes ignores env changes mid-process).
130
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sinapse-doctor-fresh-'));
131
- fakeHome = fs.mkdtempSync(path.join(os.tmpdir(), 'sinapse-doctor-home-'));
132
- });
133
-
134
- afterEach(() => {
135
- try { fs.rmSync(tempDir, { recursive: true, force: true }); } catch {}
136
- try { fs.rmSync(fakeHome, { recursive: true, force: true }); } catch {}
137
- });
138
-
139
- it('should return notInstalled=true when no SINAPSE markers exist', async () => {
140
- const result = await runDoctorChecks({ projectRoot: tempDir, homeDir: fakeHome });
141
- expect(result.data.notInstalled).toBe(true);
142
- expect(result.data.installCommand).toBe('npx sinapse-ai install');
143
- expect(result.data.checks).toHaveLength(0);
144
- });
145
-
146
- it('should produce friendly NOT_INSTALLED text (no FAIL lines)', async () => {
147
- const result = await runDoctorChecks({ projectRoot: tempDir, homeDir: fakeHome });
148
- expect(result.formatted).toContain('SINAPSE is not installed');
149
- expect(result.formatted).toContain('npx sinapse-ai install');
150
- expect(result.formatted).not.toContain('[FAIL]');
151
- });
152
-
153
- it('should include notInstalled flag in JSON output', async () => {
154
- const result = await runDoctorChecks({ json: true, projectRoot: tempDir, homeDir: fakeHome });
155
- const parsed = JSON.parse(result.formatted);
156
- expect(parsed.notInstalled).toBe(true);
157
- expect(parsed.installCommand).toBe('npx sinapse-ai install');
158
- });
159
-
160
- it('should map to exit code 4', async () => {
161
- const result = await runDoctorChecks({ projectRoot: tempDir, homeDir: fakeHome });
162
- expect(resolveExitCode(result)).toBe(4);
163
- });
164
-
165
- it('should fall back to full check suite when a project marker exists', async () => {
166
- // Drop a .sinapse-ai/ dir into the temp project. That alone should
167
- // flip detection to installed=true and run the full check path.
168
- fs.mkdirSync(path.join(tempDir, '.sinapse-ai'), { recursive: true });
169
- const result = await runDoctorChecks({ projectRoot: tempDir, homeDir: fakeHome });
170
- expect(result.data.notInstalled).toBeUndefined();
171
- expect(result.data.checks.length).toBeGreaterThan(0);
172
- });
173
- });
174
-
175
- describe('JSON output schema (AC3)', () => {
176
- it('should match expected JSON schema', async () => {
177
- const result = await runDoctorChecks({ json: true, projectRoot });
178
- const parsed = JSON.parse(result.formatted);
179
-
180
- expect(parsed).toHaveProperty('version');
181
- expect(parsed).toHaveProperty('timestamp');
182
- expect(parsed).toHaveProperty('summary');
183
- expect(parsed.summary).toHaveProperty('pass');
184
- expect(parsed.summary).toHaveProperty('warn');
185
- expect(parsed.summary).toHaveProperty('fail');
186
- expect(parsed.summary).toHaveProperty('info');
187
- expect(parsed).toHaveProperty('checks');
188
- expect(Array.isArray(parsed.checks)).toBe(true);
189
- });
190
- });
191
- });
192
-
@@ -1,186 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Entity Registry Bootstrap Tests (Story INS-4.6)
5
- *
6
- * Validates that the installer calls populate-entity-registry.js during install,
7
- * handles failures gracefully, and that sinapse doctor can verify the registry.
8
- */
9
-
10
- const fs = require('fs');
11
- const path = require('path');
12
-
13
- const WIZARD_PATH = path.join(__dirname, '..', '..', 'src', 'wizard', 'index.js');
14
- const POPULATE_SCRIPT = path.join(
15
- __dirname, '..', '..', '..', '..', '.sinapse-ai', 'development', 'scripts', 'populate-entity-registry.js'
16
- );
17
- const DOCTOR_CHECK = path.join(
18
- __dirname, '..', '..', '..', '..', '.sinapse-ai', 'core', 'doctor', 'checks', 'entity-registry.js'
19
- );
20
- const REGISTRY_PATH = path.join(
21
- __dirname, '..', '..', '..', '..', '.sinapse-ai', 'data', 'entity-registry.yaml'
22
- );
23
- const PRE_PUSH_HOOK = path.join(__dirname, '..', '..', '..', '..', '.husky', 'pre-push');
24
- const IDS_PRE_PUSH = path.join(
25
- __dirname, '..', '..', '..', '..', '.sinapse-ai', 'hooks', 'ids-pre-push.js'
26
- );
27
-
28
- describe('Entity Registry Bootstrap (Story INS-4.6)', () => {
29
- let wizardSource;
30
-
31
- beforeAll(() => {
32
- wizardSource = fs.readFileSync(WIZARD_PATH, 'utf8');
33
- });
34
-
35
- describe('AC1: Bootstrap called during install', () => {
36
- test('wizard calls populate-entity-registry.js', () => {
37
- expect(wizardSource).toContain('populate-entity-registry.js');
38
- expect(wizardSource).toContain('Bootstrapping entity registry');
39
- });
40
-
41
- test('bootstrap runs after .sinapse-ai/ copy (injection order)', () => {
42
- const sinapseCoreIdx = wizardSource.indexOf('SINAPSE core installed');
43
- const bootstrapIdx = wizardSource.indexOf('Bootstrapping entity registry');
44
- const envConfigIdx = wizardSource.indexOf('Configuring environment');
45
-
46
- // Bootstrap must come after sinapse-ai install
47
- expect(bootstrapIdx).toBeGreaterThan(sinapseCoreIdx);
48
- // Bootstrap must come before environment configuration
49
- expect(bootstrapIdx).toBeLessThan(envConfigIdx);
50
- });
51
-
52
- test('bootstrap has try/catch — failure does not abort install', () => {
53
- // Verify the bootstrap block is wrapped in try/catch
54
- expect(wizardSource).toContain("answers.entityRegistryStatus = 'failed'");
55
- expect(wizardSource).toContain('Entity registry bootstrap failed');
56
- // Should warn, not throw
57
- expect(wizardSource).toContain("run 'sinapse doctor' post-install");
58
- });
59
-
60
- test('bootstrap uses 30s timeout guard', () => {
61
- expect(wizardSource).toContain('timeout: 30000');
62
- });
63
-
64
- test('bootstrap reports entity count on success', () => {
65
- expect(wizardSource).toContain("answers.entityRegistryStatus = 'populated'");
66
- expect(wizardSource).toContain('answers.entityRegistryCount');
67
- expect(wizardSource).toContain('answers.entityRegistryMs');
68
- });
69
-
70
- test('bootstrap handles missing script gracefully', () => {
71
- expect(wizardSource).toContain("answers.entityRegistryStatus = 'skipped'");
72
- expect(wizardSource).toContain('Entity registry script not found');
73
- });
74
- });
75
-
76
- describe('AC2: Sanity check (relative threshold)', () => {
77
- test('sinapse doctor entity-registry check exists', () => {
78
- expect(fs.existsSync(DOCTOR_CHECK)).toBe(true);
79
- });
80
-
81
- test('doctor check uses relative validation (file exists + non-empty), not fixed threshold', () => {
82
- const checkSource = fs.readFileSync(DOCTOR_CHECK, 'utf8');
83
-
84
- // Should check file existence
85
- expect(checkSource).toContain('existsSync');
86
- // Should NOT have hardcoded threshold like >= 500
87
- expect(checkSource).not.toMatch(/>= ?\d{3}/);
88
- // Should report line count (relative measure)
89
- expect(checkSource).toContain('lineCount');
90
- });
91
-
92
- test('doctor check validates recency (mtime)', () => {
93
- const checkSource = fs.readFileSync(DOCTOR_CHECK, 'utf8');
94
- expect(checkSource).toContain('mtimeMs');
95
- expect(checkSource).toContain('MAX_AGE_MS');
96
- });
97
- });
98
-
99
- describe('AC3: No duplication with pre-push hook', () => {
100
- test('pre-push hook calls pre-push-safety.js, not populate script', () => {
101
- const hookContent = fs.readFileSync(PRE_PUSH_HOOK, 'utf8');
102
- expect(hookContent).toContain('pre-push-safety.js');
103
- expect(hookContent).not.toContain('populate-entity-registry.js');
104
- });
105
-
106
- test('ids-pre-push.js uses RegistryUpdater.processChanges (incremental)', () => {
107
- const idsSource = fs.readFileSync(IDS_PRE_PUSH, 'utf8');
108
- expect(idsSource).toContain('RegistryUpdater');
109
- expect(idsSource).toContain('processChanges');
110
- });
111
-
112
- test('bootstrap uses populate-entity-registry.js (full scan), distinct from incremental', () => {
113
- // Wizard calls populate-entity-registry.js
114
- expect(wizardSource).toContain('populate-entity-registry.js');
115
- // Wizard does NOT call ids-pre-push.js
116
- expect(wizardSource).not.toContain('ids-pre-push.js');
117
- });
118
- });
119
-
120
- describe('AC4: Performance guard', () => {
121
- test('populate-entity-registry.js exists and is executable', () => {
122
- expect(fs.existsSync(POPULATE_SCRIPT)).toBe(true);
123
- });
124
-
125
- test('populate script has programmatic API (module.exports)', () => {
126
- const scriptSource = fs.readFileSync(POPULATE_SCRIPT, 'utf8');
127
- expect(scriptSource).toContain('module.exports');
128
- expect(scriptSource).toContain('populate');
129
- });
130
-
131
- test('measured runtime is well under 15s threshold', () => {
132
- // Run the actual script and measure time
133
- const { execSync } = require('child_process');
134
- const projectRoot = path.join(__dirname, '..', '..', '..', '..');
135
- const start = Date.now();
136
-
137
- try {
138
- execSync(`node "${POPULATE_SCRIPT}"`, {
139
- cwd: projectRoot,
140
- encoding: 'utf8',
141
- timeout: 30000,
142
- stdio: 'pipe',
143
- });
144
- } catch {
145
- // Script may fail in some environments — that's ok for timing test
146
- console.log('SKIP: populate script execution failed — timing not measured');
147
- return;
148
- }
149
-
150
- const elapsed = Date.now() - start;
151
- // Must be under 15s (AC4 threshold)
152
- expect(elapsed).toBeLessThan(15000);
153
- console.log(`Measured runtime: ${(elapsed / 1000).toFixed(2)}s`);
154
- });
155
- });
156
-
157
- describe('AC5: Post-bootstrap verification', () => {
158
- test('entity-registry.yaml exists after bootstrap', () => {
159
- expect(fs.existsSync(REGISTRY_PATH)).toBe(true);
160
- });
161
-
162
- test('entity-registry.yaml has at least 1 entity (non-empty)', () => {
163
- const content = fs.readFileSync(REGISTRY_PATH, 'utf8');
164
- const match = content.match(/entityCount:\s*(\d+)/);
165
- expect(match).not.toBeNull();
166
- const count = parseInt(match[1], 10);
167
- expect(count).toBeGreaterThan(0);
168
- });
169
-
170
- // NOTE: This test depends on AC4 "measured runtime" test running first,
171
- // which executes populate-entity-registry.js and refreshes the file mtime.
172
- test('entity-registry.yaml updatedAt is recent (within 5 minutes)', () => {
173
- const stat = fs.statSync(REGISTRY_PATH);
174
- const ageMs = Date.now() - stat.mtimeMs;
175
- const FIVE_MINUTES = 5 * 60 * 1000;
176
- expect(ageMs).toBeLessThan(FIVE_MINUTES);
177
- });
178
-
179
- test('sinapse doctor entity-registry check passes on current registry', async () => {
180
- const { run } = require(DOCTOR_CHECK);
181
- const projectRoot = path.join(__dirname, '..', '..', '..', '..');
182
- const result = await run({ projectRoot });
183
- expect(result.status).toBe('PASS');
184
- });
185
- });
186
- });
@@ -1,187 +0,0 @@
1
- /**
2
- * Unit Tests: .env Template Generator
3
- * Story 1.6: Environment Configuration
4
- *
5
- * Tests for env-template.js
6
- */
7
-
8
- const { generateEnvContent, generateEnvExample } = require('../../src/config/templates/env-template');
9
-
10
- describe('.env Template Generator', () => {
11
- describe('generateEnvContent', () => {
12
- it('should generate .env with empty API keys when none provided', () => {
13
- const content = generateEnvContent();
14
-
15
- expect(content).toContain('NODE_ENV=development');
16
- // Version-agnostic: check SINAPSE_VERSION exists with valid semver format
17
- expect(content).toMatch(/SINAPSE_VERSION=\d+\.\d+\.\d+/);
18
- expect(content).toContain('OPENAI_API_KEY=');
19
- expect(content).toContain('ANTHROPIC_API_KEY=');
20
- expect(content).toContain('# SINAPSE Environment Configuration');
21
- });
22
-
23
- it('should generate .env with provided API keys', () => {
24
- const apiKeys = {
25
- openai: 'sk-test-openai-key',
26
- anthropic: 'sk-ant-test-anthropic-key',
27
- };
28
-
29
- const content = generateEnvContent(apiKeys);
30
-
31
- expect(content).toContain('OPENAI_API_KEY=sk-test-openai-key');
32
- expect(content).toContain('ANTHROPIC_API_KEY=sk-ant-test-anthropic-key');
33
- });
34
-
35
- it('should generate .env with optional service API keys', () => {
36
- const apiKeys = {
37
- clickup: 'clickup-test-key',
38
- github: 'ghp-test-token',
39
- exa: 'exa-test-key',
40
- };
41
-
42
- const content = generateEnvContent(apiKeys);
43
-
44
- expect(content).toContain('CLICKUP_API_KEY=clickup-test-key');
45
- expect(content).toContain('GITHUB_TOKEN=ghp-test-token');
46
- expect(content).toContain('EXA_API_KEY=exa-test-key');
47
- });
48
-
49
- it('should include helpful comments', () => {
50
- const content = generateEnvContent();
51
-
52
- expect(content).toContain('# LLM Providers');
53
- expect(content).toContain('# Search & Research Tools');
54
- expect(content).toContain('Get your key at:');
55
- });
56
-
57
- it('should not contain sensitive data in comments', () => {
58
- const content = generateEnvContent();
59
-
60
- // Should not have example API keys or credentials in comments
61
- expect(content).not.toMatch(/sk-[a-zA-Z0-9]{20,}/);
62
- expect(content).not.toMatch(/example.*key.*[a-zA-Z0-9]{20,}/i);
63
- });
64
-
65
- it('should use KEY=value format without spaces', () => {
66
- const apiKeys = { openai: 'test-key' };
67
- const content = generateEnvContent(apiKeys);
68
-
69
- // Check no spaces around =
70
- const lines = content.split('\n').filter(line => !line.startsWith('#') && line.trim());
71
- lines.forEach(line => {
72
- if (line.includes('=')) {
73
- expect(line).toMatch(/^[A-Z0-9_]+=.*/);
74
- // Check there are NO spaces before or after the = sign
75
- expect(line).not.toMatch(/\s=/); // No space before =
76
- expect(line).not.toMatch(/=\s[^=]*$/); // No space after = (except in comments)
77
- }
78
- });
79
- });
80
- });
81
-
82
- describe('generateEnvExample', () => {
83
- it('should generate .env.example with empty values', () => {
84
- const content = generateEnvExample();
85
-
86
- expect(content).toContain('NODE_ENV=development');
87
- // Version-agnostic: check SINAPSE_VERSION exists with valid semver format
88
- expect(content).toMatch(/SINAPSE_VERSION=\d+\.\d+\.\d+/);
89
- expect(content).toContain('OPENAI_API_KEY=');
90
- expect(content).toContain('ANTHROPIC_API_KEY=');
91
- expect(content).toContain('CLICKUP_API_KEY=');
92
- });
93
-
94
- it('should not contain any actual API keys', () => {
95
- const content = generateEnvExample();
96
-
97
- // All API key fields should be empty
98
- const apiKeyLines = content.split('\n').filter(line =>
99
- line.includes('_API_KEY=') || line.includes('_TOKEN='),
100
- );
101
-
102
- apiKeyLines.forEach(line => {
103
- const [, value] = line.split('=');
104
- expect(value.trim()).toBe('');
105
- });
106
- });
107
-
108
- it('should include helpful comments with links', () => {
109
- const content = generateEnvExample();
110
-
111
- expect(content).toContain('https://platform.openai.com');
112
- expect(content).toContain('https://console.anthropic.com');
113
- expect(content).toContain('ClickUp Settings');
114
- expect(content).toContain('https://github.com/settings/tokens');
115
- });
116
-
117
- it('should be safe to commit', () => {
118
- const content = generateEnvExample();
119
-
120
- // Should not contain any of these sensitive patterns
121
- const sensitivePatterns = [
122
- /sk-[a-zA-Z0-9]{20,}/, // OpenAI keys
123
- /sk-ant-[a-zA-Z0-9]{30,}/, // Anthropic keys
124
- /ghp_[a-zA-Z0-9]+/, // GitHub tokens
125
- ];
126
-
127
- sensitivePatterns.forEach(pattern => {
128
- expect(content).not.toMatch(pattern);
129
- });
130
-
131
- // Check that no API key fields have actual values (only empty or commented)
132
- const lines = content.split('\n').filter(line => !line.trim().startsWith('#'));
133
- lines.forEach(line => {
134
- if (line.includes('PASSWORD') || line.includes('SECRET') || line.includes('KEY') || line.includes('TOKEN')) {
135
- const [key, value] = line.split('=');
136
- if (value !== undefined) {
137
- expect(value.trim()).toBe('');
138
- }
139
- }
140
- });
141
- });
142
-
143
- it('should match .env structure but with empty values', () => {
144
- const envContent = generateEnvContent({ openai: 'test', anthropic: 'test' });
145
- const exampleContent = generateEnvExample();
146
-
147
- // Extract non-comment, non-empty lines
148
- const envKeys = envContent.split('\n')
149
- .filter(line => line.trim() && !line.startsWith('#'))
150
- .map(line => line.split('=')[0]);
151
-
152
- const exampleKeys = exampleContent.split('\n')
153
- .filter(line => line.trim() && !line.startsWith('#'))
154
- .map(line => line.split('=')[0]);
155
-
156
- // Both should have the same keys
157
- expect(exampleKeys.sort()).toEqual(envKeys.sort());
158
- });
159
- });
160
-
161
- describe('Content Quality', () => {
162
- it('should have proper line endings', () => {
163
- const content = generateEnvContent();
164
-
165
- // Should use \n for line endings
166
- expect(content).not.toContain('\r\n');
167
- expect(content.split('\n').length).toBeGreaterThan(10);
168
- });
169
-
170
- it('should organize content in sections', () => {
171
- const content = generateEnvContent();
172
-
173
- // Should have clear section headers
174
- expect(content).toContain('# SINAPSE Core Configuration');
175
- expect(content).toContain('# LLM Providers');
176
- expect(content).toContain('# Search & Research Tools');
177
- });
178
-
179
- it('should include usage instructions', () => {
180
- const content = generateEnvContent();
181
-
182
- // Should help users understand what to do
183
- expect(content).toContain('DO NOT commit');
184
- expect(content).toContain('Get yours at:');
185
- });
186
- });
187
- });