sinapse-ai 1.16.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/.claude/hooks/doc-first-gate.cjs +156 -0
  2. package/.claude/hooks/enforce-story-gate.cjs +6 -2
  3. package/.claude/rules/documentation-first.md +6 -0
  4. package/.claude/rules/hook-governance.md +1 -0
  5. package/.sinapse-ai/constitution.md +3 -3
  6. package/.sinapse-ai/core/atlas/atlas-data.js +278 -0
  7. package/.sinapse-ai/core/atlas/flows-pt.js +253 -0
  8. package/.sinapse-ai/core/atlas/flows.js +266 -0
  9. package/.sinapse-ai/core/atlas/index.js +62 -0
  10. package/.sinapse-ai/core/atlas/render-html.js +216 -0
  11. package/.sinapse-ai/core/atlas/render-markdown.js +313 -0
  12. package/.sinapse-ai/core/atlas/render-research-card.js +164 -0
  13. package/.sinapse-ai/core/code-intel/registry-syncer.js +5 -3
  14. package/.sinapse-ai/core/doctor/checks/agent-memory.js +7 -5
  15. package/.sinapse-ai/core/doctor/checks/claude-md.js +13 -0
  16. package/.sinapse-ai/core/doctor/checks/constitution-consistency.js +1 -0
  17. package/.sinapse-ai/core/doctor/checks/hooks-claude-count.js +11 -0
  18. package/.sinapse-ai/core/doctor/checks/settings-json.js +16 -2
  19. package/.sinapse-ai/core/doctor/index.js +27 -0
  20. package/.sinapse-ai/core/execution/build-orchestrator.js +192 -8
  21. package/.sinapse-ai/core/external-executors/delegate-cli.js +6 -2
  22. package/.sinapse-ai/core/health-check/checks/project/constitution-consistency.js +2 -1
  23. package/.sinapse-ai/core/ideation/ideation-engine.js +10 -8
  24. package/.sinapse-ai/core/mcp/config-migrator.js +8 -5
  25. package/.sinapse-ai/core/mcp/global-config-manager.js +4 -1
  26. package/.sinapse-ai/core/mcp/symlink-manager.js +6 -3
  27. package/.sinapse-ai/core/orchestration/brownfield-handler.js +5 -4
  28. package/.sinapse-ai/core/orchestration/build-command.js +136 -0
  29. package/.sinapse-ai/core/orchestration/doc-first-resolver.js +322 -0
  30. package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +3 -0
  31. package/.sinapse-ai/core/orchestration/gate-evaluator.js +58 -9
  32. package/.sinapse-ai/core/orchestration/route-command.js +97 -0
  33. package/.sinapse-ai/core/orchestration/session-state.js +19 -2
  34. package/.sinapse-ai/core/orchestration/terminal-spawner.js +24 -1
  35. package/.sinapse-ai/core/orchestration/workflow-executor.js +102 -3
  36. package/.sinapse-ai/core/quality-gates/focus-area-recommender.js +15 -11
  37. package/.sinapse-ai/core/registry/build-registry.js +3 -2
  38. package/.sinapse-ai/core/synapse/scripts/generate-constitution.js +1 -0
  39. package/.sinapse-ai/core/synapse/utils/atomic-write.js +34 -9
  40. package/.sinapse-ai/core-config.yaml +5 -1
  41. package/.sinapse-ai/data/capability-detection.js +3 -3
  42. package/.sinapse-ai/data/entity-registry.yaml +288 -90
  43. package/.sinapse-ai/data/mcp-discipline.js +1 -1
  44. package/.sinapse-ai/data/mcp-tool-examples.yaml +8 -8
  45. package/.sinapse-ai/data/tok2-validation.js +1 -1
  46. package/.sinapse-ai/data/tool-registry.yaml +4 -3
  47. package/.sinapse-ai/development/agents/snps-orqx.md +14 -5
  48. package/.sinapse-ai/development/scripts/migrate-task-to-v2.js +1 -1
  49. package/.sinapse-ai/development/scripts/validate-task-v2.js +67 -4
  50. package/.sinapse-ai/development/tasks/advanced-elicitation.md +3 -3
  51. package/.sinapse-ai/development/tasks/analyst-facilitate-brainstorming.md +3 -3
  52. package/.sinapse-ai/development/tasks/analyze-framework.md +1 -8
  53. package/.sinapse-ai/development/tasks/analyze-performance.md +1 -8
  54. package/.sinapse-ai/development/tasks/apply-qa-fixes.md +3 -3
  55. package/.sinapse-ai/development/tasks/architect-analyze-impact.md +3 -3
  56. package/.sinapse-ai/development/tasks/audit-codebase.md +1 -8
  57. package/.sinapse-ai/development/tasks/audit-tailwind-config.md +1 -4
  58. package/.sinapse-ai/development/tasks/audit-utilities.md +1 -8
  59. package/.sinapse-ai/development/tasks/bootstrap-shadcn-library.md +3 -3
  60. package/.sinapse-ai/development/tasks/brownfield-create-epic.md +3 -3
  61. package/.sinapse-ai/development/tasks/brownfield-create-story.md +3 -3
  62. package/.sinapse-ai/development/tasks/build-component.md +2 -5
  63. package/.sinapse-ai/development/tasks/calculate-roi.md +3 -3
  64. package/.sinapse-ai/development/tasks/ci-cd-configuration.md +1 -1
  65. package/.sinapse-ai/development/tasks/cleanup-utilities.md +3 -3
  66. package/.sinapse-ai/development/tasks/collaborative-edit.md +3 -3
  67. package/.sinapse-ai/development/tasks/compose-molecule.md +2 -5
  68. package/.sinapse-ai/development/tasks/consolidate-patterns.md +3 -3
  69. package/.sinapse-ai/development/tasks/correct-course.md +3 -3
  70. package/.sinapse-ai/development/tasks/create-brownfield-story.md +2 -5
  71. package/.sinapse-ai/development/tasks/create-deep-research-prompt.md +2 -5
  72. package/.sinapse-ai/development/tasks/create-doc.md +3 -6
  73. package/.sinapse-ai/development/tasks/create-next-story.md +4 -8
  74. package/.sinapse-ai/development/tasks/create-suite.md +2 -5
  75. package/.sinapse-ai/development/tasks/create-task.md +2 -5
  76. package/.sinapse-ai/development/tasks/create-workflow.md +2 -5
  77. package/.sinapse-ai/development/tasks/db-analyze-hotpaths.md +1 -8
  78. package/.sinapse-ai/development/tasks/db-apply-migration.md +1 -8
  79. package/.sinapse-ai/development/tasks/db-bootstrap.md +1 -8
  80. package/.sinapse-ai/development/tasks/db-domain-modeling.md +1 -8
  81. package/.sinapse-ai/development/tasks/db-dry-run.md +1 -8
  82. package/.sinapse-ai/development/tasks/db-env-check.md +1 -8
  83. package/.sinapse-ai/development/tasks/db-explain.md +1 -8
  84. package/.sinapse-ai/development/tasks/db-impersonate.md +1 -8
  85. package/.sinapse-ai/development/tasks/db-load-csv.md +1 -8
  86. package/.sinapse-ai/development/tasks/db-policy-apply.md +1 -8
  87. package/.sinapse-ai/development/tasks/db-rls-audit.md +1 -8
  88. package/.sinapse-ai/development/tasks/db-rollback.md +1 -8
  89. package/.sinapse-ai/development/tasks/db-run-sql.md +1 -8
  90. package/.sinapse-ai/development/tasks/db-schema-audit.md +1 -8
  91. package/.sinapse-ai/development/tasks/db-seed.md +1 -8
  92. package/.sinapse-ai/development/tasks/db-smoke-test.md +1 -8
  93. package/.sinapse-ai/development/tasks/db-snapshot.md +1 -8
  94. package/.sinapse-ai/development/tasks/db-squad-integration.md +1 -8
  95. package/.sinapse-ai/development/tasks/db-supabase-setup.md +1 -8
  96. package/.sinapse-ai/development/tasks/db-verify-order.md +1 -8
  97. package/.sinapse-ai/development/tasks/deprecate-component.md +3 -3
  98. package/.sinapse-ai/development/tasks/dev-apply-qa-fixes.md +3 -3
  99. package/.sinapse-ai/development/tasks/dev-backlog-debt.md +3 -3
  100. package/.sinapse-ai/development/tasks/dev-develop-story.md +1 -1
  101. package/.sinapse-ai/development/tasks/dev-improve-code-quality.md +3 -3
  102. package/.sinapse-ai/development/tasks/dev-optimize-performance.md +3 -3
  103. package/.sinapse-ai/development/tasks/dev-suggest-refactoring.md +3 -3
  104. package/.sinapse-ai/development/tasks/dev-validate-next-story.md +3 -3
  105. package/.sinapse-ai/development/tasks/document-project.md +3 -3
  106. package/.sinapse-ai/development/tasks/environment-bootstrap.md +0 -4
  107. package/.sinapse-ai/development/tasks/execute-checklist.md +3 -3
  108. package/.sinapse-ai/development/tasks/export-design-tokens-dtcg.md +3 -3
  109. package/.sinapse-ai/development/tasks/extend-pattern.md +1 -8
  110. package/.sinapse-ai/development/tasks/extract-tokens.md +3 -3
  111. package/.sinapse-ai/development/tasks/facilitate-brainstorming-session.md +1 -1
  112. package/.sinapse-ai/development/tasks/generate-ai-frontend-prompt.md +2 -5
  113. package/.sinapse-ai/development/tasks/generate-documentation.md +2 -5
  114. package/.sinapse-ai/development/tasks/generate-migration-strategy.md +2 -5
  115. package/.sinapse-ai/development/tasks/generate-shock-report.md +2 -5
  116. package/.sinapse-ai/development/tasks/github-devops-github-pr-automation.md +3 -3
  117. package/.sinapse-ai/development/tasks/github-devops-repository-cleanup.md +3 -3
  118. package/.sinapse-ai/development/tasks/github-devops-version-management.md +3 -3
  119. package/.sinapse-ai/development/tasks/improve-self.md +1 -16
  120. package/.sinapse-ai/development/tasks/index-docs.md +1 -4
  121. package/.sinapse-ai/development/tasks/init-project-status.md +1 -7
  122. package/.sinapse-ai/development/tasks/integrate-squad.md +3 -3
  123. package/.sinapse-ai/development/tasks/kb-mode-interaction.md +3 -3
  124. package/.sinapse-ai/development/tasks/learn-patterns.md +3 -3
  125. package/.sinapse-ai/development/tasks/modify-agent.md +1 -8
  126. package/.sinapse-ai/development/tasks/modify-task.md +1 -8
  127. package/.sinapse-ai/development/tasks/modify-workflow.md +1 -8
  128. package/.sinapse-ai/development/tasks/po-backlog-add.md +3 -3
  129. package/.sinapse-ai/development/tasks/po-manage-story-backlog.md +3 -3
  130. package/.sinapse-ai/development/tasks/po-pull-story-from-clickup.md +3 -3
  131. package/.sinapse-ai/development/tasks/po-pull-story.md +3 -3
  132. package/.sinapse-ai/development/tasks/po-stories-index.md +3 -3
  133. package/.sinapse-ai/development/tasks/po-sync-story-to-clickup.md +3 -3
  134. package/.sinapse-ai/development/tasks/po-sync-story.md +3 -3
  135. package/.sinapse-ai/development/tasks/pr-automation.md +1 -1
  136. package/.sinapse-ai/development/tasks/propose-modification.md +3 -3
  137. package/.sinapse-ai/development/tasks/qa-backlog-add-followup.md +1 -8
  138. package/.sinapse-ai/development/tasks/qa-create-fix-request.md +1 -4
  139. package/.sinapse-ai/development/tasks/qa-gate.md +1 -8
  140. package/.sinapse-ai/development/tasks/qa-generate-tests.md +1 -8
  141. package/.sinapse-ai/development/tasks/qa-nfr-assess.md +1 -8
  142. package/.sinapse-ai/development/tasks/qa-review-proposal.md +1 -8
  143. package/.sinapse-ai/development/tasks/qa-review-story.md +1 -8
  144. package/.sinapse-ai/development/tasks/qa-risk-profile.md +1 -8
  145. package/.sinapse-ai/development/tasks/qa-run-tests.md +1 -8
  146. package/.sinapse-ai/development/tasks/qa-test-design.md +1 -8
  147. package/.sinapse-ai/development/tasks/qa-trace-requirements.md +1 -8
  148. package/.sinapse-ai/development/tasks/release-management.md +1 -1
  149. package/.sinapse-ai/development/tasks/security-audit.md +1 -4
  150. package/.sinapse-ai/development/tasks/security-scan.md +1 -4
  151. package/.sinapse-ai/development/tasks/setup-database.md +2 -11
  152. package/.sinapse-ai/development/tasks/setup-design-system.md +2 -11
  153. package/.sinapse-ai/development/tasks/shard-doc.md +3 -3
  154. package/.sinapse-ai/development/tasks/sm-create-next-story.md +3 -3
  155. package/.sinapse-ai/development/tasks/spec-gather-requirements.md +11 -0
  156. package/.sinapse-ai/development/tasks/sync-documentation.md +1 -6
  157. package/.sinapse-ai/development/tasks/tailwind-upgrade.md +3 -3
  158. package/.sinapse-ai/development/tasks/test-as-user.md +3 -3
  159. package/.sinapse-ai/development/tasks/undo-last.md +2 -5
  160. package/.sinapse-ai/development/tasks/update-manifest.md +1 -8
  161. package/.sinapse-ai/development/tasks/ux-create-wireframe.md +1 -1
  162. package/.sinapse-ai/development/tasks/ux-ds-scan-artifact.md +3 -3
  163. package/.sinapse-ai/development/tasks/ux-user-research.md +3 -3
  164. package/.sinapse-ai/development/tasks/validate-next-story.md +1 -8
  165. package/.sinapse-ai/development/templates/approval-table.md +106 -0
  166. package/.sinapse-ai/development/templates/chrome-brain/scripts/chrome-ensure.cjs +1 -1
  167. package/.sinapse-ai/development/workflows/spec-pipeline.yaml +1 -0
  168. package/.sinapse-ai/git-hooks/post-commit +0 -0
  169. package/.sinapse-ai/git-hooks/pre-commit +0 -0
  170. package/.sinapse-ai/git-hooks/pre-push +0 -0
  171. package/.sinapse-ai/infrastructure/scripts/changelog-generator.js +5 -1
  172. package/.sinapse-ai/infrastructure/scripts/pattern-extractor.js +11 -2
  173. package/.sinapse-ai/infrastructure/scripts/test-utilities.js +34 -13
  174. package/.sinapse-ai/infrastructure/scripts/usage-analytics.js +9 -5
  175. package/.sinapse-ai/infrastructure/scripts/validate-claude-integration.js +10 -2
  176. package/.sinapse-ai/install-manifest.yaml +364 -320
  177. package/.sinapse-ai/lib/build.json +1 -0
  178. package/.sinapse-ai/product/templates/personalized-task-template-v2.md +4 -2
  179. package/.sinapse-ai/product/templates/prd-tmpl.yaml +6 -2
  180. package/.sinapse-ai/product/templates/statusline/statusline-script.js +7 -3
  181. package/CHANGELOG.md +85 -7
  182. package/README.en.md +5 -5
  183. package/README.md +5 -5
  184. package/bin/cli.js +1 -1
  185. package/bin/commands/install.js +288 -114
  186. package/bin/commands/local.js +11 -0
  187. package/bin/lib/command-generator.js +31 -2
  188. package/bin/sinapse.js +121 -0
  189. package/docs/README.md +1 -1
  190. package/docs/agent-reference-guide.md +1 -1
  191. package/docs/community/README-community-snippet-core.md +1 -1
  192. package/docs/community/README-community-snippet-mcp.md +1 -1
  193. package/docs/community/README-community-snippet-squads.md +1 -1
  194. package/docs/examples/quickstart-recording.md +1 -1
  195. package/docs/framework/README.md +1 -1
  196. package/docs/framework/architecture-overview.md +1 -0
  197. package/docs/framework/atlas/OPERATING-ATLAS.md +537 -0
  198. package/docs/framework/atlas/README.md +34 -0
  199. package/docs/framework/atlas/atlas-data.json +2810 -0
  200. package/docs/framework/atlas/atlas.html +392 -0
  201. package/docs/framework/coding-standards.md +1 -1
  202. package/docs/framework/core-architecture.md +1 -1
  203. package/docs/framework/guiding-principles.md +1 -1
  204. package/docs/framework/source-tree.md +1 -1
  205. package/docs/framework/tech-stack.md +1 -1
  206. package/docs/framework/versioning-and-releases.md +1 -1
  207. package/docs/getting-started.md +1 -1
  208. package/docs/guides/agent-reference.md +1 -1
  209. package/docs/guides/agent-selection-guide.md +1 -1
  210. package/docs/guides/api-reference.md +1 -1
  211. package/docs/guides/contextual-greeting-system-guide.md +1 -1
  212. package/docs/guides/contributing-squads.md +1 -1
  213. package/docs/guides/development-setup.md +1 -1
  214. package/docs/guides/git-workflow-guide.md +1 -1
  215. package/docs/guides/installation-troubleshooting.md +1 -1
  216. package/docs/guides/llm-routing.md +1 -1
  217. package/docs/guides/mcp-global-setup.md +1 -1
  218. package/docs/guides/meta-agent-commands.md +1 -1
  219. package/docs/guides/project-status-feature.md +1 -1
  220. package/docs/guides/quality-dashboard.md +1 -1
  221. package/docs/guides/quality-gates.md +1 -1
  222. package/docs/guides/security-hardening.md +1 -1
  223. package/docs/guides/service-discovery.md +19 -22
  224. package/docs/guides/squad-examples/README.md +1 -1
  225. package/docs/guides/squad-migration.md +1 -1
  226. package/docs/guides/squads-guide.md +1 -1
  227. package/docs/guides/squads-overview.md +10 -13
  228. package/docs/guides/template-engine-v2.md +1 -1
  229. package/docs/guides/testing-guide.md +1 -1
  230. package/docs/guides/user-guide.md +30 -26
  231. package/docs/installation/README.md +3 -3
  232. package/docs/installation/faq.md +1 -1
  233. package/docs/installation/linux.md +2 -2
  234. package/docs/installation/macos.md +1 -1
  235. package/docs/installation/npx-install.md +1 -1
  236. package/docs/installation/troubleshooting.md +1 -1
  237. package/docs/installation/uninstallation.md +1 -1
  238. package/docs/installation/v4-quick-start.md +1 -1
  239. package/docs/installation/windows.md +2 -2
  240. package/docs/pt/CHANGELOG.md +1 -1
  241. package/docs/pt/DOCUMENTATION-ROADMAP.md +1 -1
  242. package/docs/pt/ENVIRONMENT.md +1 -1
  243. package/docs/pt/FEATURE_PROCESS.md +2 -2
  244. package/docs/pt/GUIDING-PRINCIPLES.md +2 -2
  245. package/docs/pt/agent-reference-guide.md +3 -3
  246. package/docs/pt/architecture/ARCHITECTURE-INDEX.md +2 -2
  247. package/docs/pt/architecture/ade-architecture.md +1 -1
  248. package/docs/pt/architecture/agent-config-audit.md +1 -1
  249. package/docs/pt/architecture/agent-responsibility-matrix.md +1 -1
  250. package/docs/pt/architecture/agent-tool-integration-guide.md +1 -1
  251. package/docs/pt/architecture/ci-cd.md +1 -1
  252. package/docs/pt/architecture/coding-standards.md +1 -1
  253. package/docs/pt/architecture/contribution-workflow-research.md +1 -1
  254. package/docs/pt/architecture/dashboard-architecture.md +1 -1
  255. package/docs/pt/architecture/dashboard-realtime.md +1 -1
  256. package/docs/pt/architecture/hcs-check-specifications.md +1 -1
  257. package/docs/pt/architecture/hcs-execution-modes.md +1 -1
  258. package/docs/pt/architecture/hcs-self-healing-spec.md +1 -1
  259. package/docs/pt/architecture/high-level-architecture.md +1 -1
  260. package/docs/pt/architecture/introduction.md +1 -1
  261. package/docs/pt/architecture/mcp-api-keys-management.md +3 -3
  262. package/docs/pt/architecture/mcp-system-diagrams.md +1 -1
  263. package/docs/pt/architecture/module-system.md +4 -4
  264. package/docs/pt/architecture/multi-repo-strategy.md +2 -2
  265. package/docs/pt/architecture/source-tree.md +1 -1
  266. package/docs/pt/architecture/squad-improvement-analysis.md +1 -1
  267. package/docs/pt/architecture/squad-improvement-recommended-approach.md +1 -1
  268. package/docs/pt/architecture/tech-stack.md +1 -1
  269. package/docs/pt/architecture/utility-integration-guide.md +1 -1
  270. package/docs/pt/code-of-conduct.md +1 -1
  271. package/docs/pt/community/README-community-snippet-core.md +1 -1
  272. package/docs/pt/community/README-community-snippet-mcp.md +2 -2
  273. package/docs/pt/contributing.md +7 -7
  274. package/docs/pt/core-architecture.md +1 -1
  275. package/docs/pt/docker-mcp-setup.md +1 -1
  276. package/docs/pt/framework/README.md +1 -1
  277. package/docs/pt/framework/coding-standards.md +1 -1
  278. package/docs/pt/framework/source-tree.md +1 -1
  279. package/docs/pt/framework/tech-stack.md +1 -1
  280. package/docs/pt/getting-started.md +1 -1
  281. package/docs/pt/git-workflow-guide.md +1 -1
  282. package/docs/pt/guides/README.md +3 -3
  283. package/docs/pt/guides/agent-selection-guide.md +2 -2
  284. package/docs/pt/guides/api-reference.md +1 -1
  285. package/docs/pt/guides/contextual-greeting-system-guide.md +1 -1
  286. package/docs/pt/guides/contributing-squads.md +1 -1
  287. package/docs/pt/guides/development-setup.md +1 -1
  288. package/docs/pt/guides/installation-troubleshooting.md +1 -1
  289. package/docs/pt/guides/llm-routing.md +1 -1
  290. package/docs/pt/guides/mcp/desktop-commander.md +1 -1
  291. package/docs/pt/guides/mcp/docker-gateway-tutorial.md +1 -1
  292. package/docs/pt/guides/mcp-global-setup.md +1 -1
  293. package/docs/pt/guides/project-status-feature.md +1 -1
  294. package/docs/pt/guides/quality-dashboard.md +1 -1
  295. package/docs/pt/guides/quality-gates.md +1 -1
  296. package/docs/pt/guides/security-hardening.md +2 -2
  297. package/docs/pt/guides/service-discovery.md +19 -22
  298. package/docs/pt/guides/squad-examples/README.md +1 -1
  299. package/docs/pt/guides/squad-migration.md +1 -1
  300. package/docs/pt/guides/squads-guide.md +1 -1
  301. package/docs/pt/guides/squads-overview.md +11 -13
  302. package/docs/pt/guides/template-engine-v2.md +1 -1
  303. package/docs/pt/guides/testing-guide.md +3 -3
  304. package/docs/pt/guides/user-guide.md +30 -26
  305. package/docs/pt/guides/workflows-guide.md +1 -1
  306. package/docs/pt/how-to-contribute-with-pull-requests.md +1 -1
  307. package/docs/pt/ide-integration.md +2 -2
  308. package/docs/pt/installation/README.md +1 -1
  309. package/docs/pt/installation/faq.md +1 -1
  310. package/docs/pt/installation/linux.md +1 -1
  311. package/docs/pt/installation/macos.md +1 -1
  312. package/docs/pt/installation/troubleshooting.md +1 -1
  313. package/docs/pt/installation/v4-quick-start.md +1 -1
  314. package/docs/pt/installation/windows.md +1 -1
  315. package/docs/pt/meta-agent-commands.md +1 -1
  316. package/docs/pt/migration-guide.md +1 -1
  317. package/docs/pt/npx-install.md +1 -1
  318. package/docs/pt/performance-tuning-guide.md +1 -1
  319. package/docs/pt/platforms/claude-code.md +2 -2
  320. package/docs/pt/roadmap.md +2 -2
  321. package/docs/pt/security-best-practices.md +2 -2
  322. package/docs/pt/security.md +1 -1
  323. package/docs/pt/sinapse-nomenclature-specification.md +1 -1
  324. package/docs/pt/troubleshooting.md +1 -1
  325. package/docs/pt/uninstallation.md +1 -1
  326. package/docs/pt/versioning-and-releases.md +1 -1
  327. package/docs/security/overview.md +1 -1
  328. package/docs/security/security-best-practices.md +2 -2
  329. package/docs/sinapse-workflows/README.md +1 -1
  330. package/package.json +2 -1
  331. package/packages/installer/package.json +1 -0
  332. package/packages/installer/src/wizard/feedback.js +18 -2
  333. package/packages/installer/src/wizard/i18n.js +78 -0
  334. package/packages/installer/src/wizard/ide-config-generator.js +14 -9
  335. package/packages/installer/src/wizard/index.js +16 -16
  336. package/packages/installer/src/wizard/validation/report-generator.js +22 -21
  337. package/packages/installer/src/wizard/validation/troubleshooting-system.js +19 -13
  338. package/scripts/gen-agent-badges.js +1 -1
  339. package/scripts/install-chrome-brain.sh +2 -2
  340. package/scripts/package-synapse.js +14 -5
  341. package/scripts/prepare-hooks.js +19 -0
  342. package/scripts/validate-agent-codenames.js +174 -0
  343. package/scripts/validate-all.js +1 -0
  344. package/scripts/validate-no-personal-leaks.js +24 -9
  345. package/sinapse/agents/sinapse-orqx.md +5 -5
  346. package/sinapse/agents/snps-orqx.md +5 -5
  347. package/squads/squad-brand/agents/brand-creative-engineer.md +5 -5
  348. package/squads/squad-brand/squad.yaml +6 -6
  349. package/squads/squad-content/agents/content-engineer.md +7 -7
  350. package/squads/squad-content/squad.yaml +5 -5
  351. package/squads/squad-copy/knowledge-base/consequence-headline-patterns.md +2 -2
  352. package/squads/squad-courses/agents/production-director.md +5 -5
  353. package/squads/squad-courses/squad.yaml +1 -1
  354. package/docs/guides/hooks-two-layers.md +0 -66
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Route Command — read-only doc-first routing observability.
3
+ *
4
+ * Renders the deterministic routing decision for a briefing: project type →
5
+ * workflow → required upstream docs (exist/missing) → doc-first gate verdict.
6
+ *
7
+ * Intentionally lightweight: requires ONLY `doc-first-resolver` (fs + constants)
8
+ * and chalk. It does NOT pull the heavy orchestration index, so it has no side
9
+ * effects and no agent spawning.
10
+ *
11
+ * NOTE: a machine-readable `--json` mode was intentionally deferred — the
12
+ * framework emits an activation/cleanup summary to stdout on process exit
13
+ * (the same trailing line seen on `sinapse orchestrate`), which would corrupt
14
+ * strict JSON output. Programmatic consumers should require `doc-first-resolver`
15
+ * directly (clean, no side effects) instead of parsing this command's stdout.
16
+ *
17
+ * @module core/orchestration/route-command
18
+ * @version 1.0.0
19
+ */
20
+
21
+ 'use strict';
22
+
23
+ const { resolveDocFirstState } = require('./doc-first-resolver');
24
+
25
+ let chalk;
26
+ try {
27
+ chalk = require('chalk');
28
+ } catch {
29
+ const id = (s) => s;
30
+ chalk = {
31
+ green: id, red: id, yellow: id, cyan: Object.assign(id, { bold: id }),
32
+ gray: id, bold: id, dim: id,
33
+ };
34
+ }
35
+
36
+ /**
37
+ * Execute the `route` command.
38
+ *
39
+ * @param {string} brief - User briefing (e.g. "criar um site pra X")
40
+ * @param {Object} [options]
41
+ * @param {string} [options.projectRoot] - Project root path
42
+ * @param {string} [options.type] - Explicit project_type override
43
+ * @returns {Promise<{success:boolean, exitCode:number, state:Object}>}
44
+ */
45
+ async function route(brief, options = {}) {
46
+ const projectRoot = options.projectRoot || process.cwd();
47
+ const state = resolveDocFirstState({ projectRoot, brief, projectType: options.type });
48
+
49
+ const ok = (b) => (b ? chalk.green('✓') : chalk.red('✗'));
50
+ const briefLabel = brief ? `"${brief}"` : '(no brief — using project state only)';
51
+
52
+ console.log(chalk.cyan('\n═══════════════════════════════════════════════════════════'));
53
+ console.log(chalk.cyan.bold(' 🧭 SINAPSE Doc-First Routing'));
54
+ console.log(chalk.cyan('═══════════════════════════════════════════════════════════\n'));
55
+
56
+ console.log(`Brief: ${chalk.gray(briefLabel)}`);
57
+ console.log(
58
+ `Project type: ${chalk.bold(state.projectType)}` +
59
+ (state.classified ? '' : chalk.gray(' (default — not matched from brief)')),
60
+ );
61
+ console.log(`Workflow: ${chalk.bold(state.workflow || 'SDC (no upstream re-doc)')}\n`);
62
+
63
+ if (state.artifacts.length) {
64
+ console.log(chalk.bold('Required upstream documents:'));
65
+ console.log(chalk.gray(' ┌──────────────────┬────────────────────────────────────┬────────┐'));
66
+ console.log(chalk.gray(' │ Document │ Path │ Status │'));
67
+ console.log(chalk.gray(' ├──────────────────┼────────────────────────────────────┼────────┤'));
68
+ for (const a of state.artifacts) {
69
+ console.log(` │ ${a.id.padEnd(16)} │ ${a.path.padEnd(34)} │ ${ok(a.exists)} │`);
70
+ }
71
+ console.log(chalk.gray(' └──────────────────┴────────────────────────────────────┴────────┘\n'));
72
+ }
73
+
74
+ console.log(chalk.bold('Doc-first gate (required before code):'));
75
+ if (state.isLightType) {
76
+ console.log(chalk.gray(' (light task — rides on existing project; only a Ready story is required)'));
77
+ console.log(` ${ok(state.gate.readyStory)} Story (status >= Ready)`);
78
+ } else {
79
+ console.log(` ${ok(state.gate.prd)} PRD ${chalk.gray('docs/prd.md')}`);
80
+ console.log(` ${ok(state.gate.epic)} Epic ${chalk.gray('docs/epics/')}`);
81
+ console.log(` ${ok(state.gate.readyStory)} Story (Ready) ${chalk.gray('docs/stories/')}`);
82
+ }
83
+
84
+ console.log('');
85
+ if (state.gate.satisfied) {
86
+ console.log(chalk.green.bold(' ✅ GATE SATISFIED — implementation may proceed.\n'));
87
+ } else {
88
+ console.log(chalk.red.bold(' 🚫 GATE BLOCKED — missing: ' + state.gate.missing.join(', ')));
89
+ console.log(
90
+ chalk.gray(` Run the ${state.workflow || 'SDC'} flow to produce these before any code.\n`),
91
+ );
92
+ }
93
+
94
+ return { success: true, exitCode: 0, state };
95
+ }
96
+
97
+ module.exports = { route };
@@ -20,6 +20,23 @@ const fsSync = require('fs');
20
20
  const path = require('path');
21
21
  const yaml = require('js-yaml');
22
22
 
23
+ // On Windows a concurrent reader / AV / Search indexer can hold a transient lock
24
+ // that makes fs.rename throw EPERM/EBUSY where POSIX would succeed. A short
25
+ // bounded retry clears virtually all of these so persistence degrades gracefully.
26
+ const TRANSIENT_LOCK_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);
27
+ async function renameWithRetry(oldPath, newPath, retries = 3, delayMs = 120) {
28
+ for (let attempt = 0; ; attempt++) {
29
+ try {
30
+ return await fs.rename(oldPath, newPath);
31
+ } catch (err) {
32
+ if (!TRANSIENT_LOCK_CODES.has(err.code) || attempt >= retries) {
33
+ throw err;
34
+ }
35
+ await new Promise((resolve) => setTimeout(resolve, delayMs * (attempt + 1)));
36
+ }
37
+ }
38
+ }
39
+
23
40
  // Constants
24
41
  const SESSION_STATE_VERSION = '1.2';
25
42
  const SESSION_STATE_FILENAME = '.session-state.yaml';
@@ -729,7 +746,7 @@ O que você quer fazer?
729
746
  for (const file of stateFiles) {
730
747
  const oldPath = path.join(this.legacyStatePath, file);
731
748
  const newPath = path.join(this.legacyStatePath, `${file}.migrated`);
732
- await fs.rename(oldPath, newPath);
749
+ await renameWithRetry(oldPath, newPath);
733
750
  }
734
751
 
735
752
  if (this.options.debug) {
@@ -775,7 +792,7 @@ O que você quer fazer?
775
792
  if (await this.exists()) {
776
793
  // Archive instead of delete
777
794
  const archivePath = `${this.stateFilePath}.discarded.${Date.now()}`;
778
- await fs.rename(this.stateFilePath, archivePath);
795
+ await renameWithRetry(this.stateFilePath, archivePath);
779
796
 
780
797
  if (this.options.debug) {
781
798
  console.log(`[SessionState] Session archived to: ${archivePath}`);
@@ -396,6 +396,25 @@ async function spawnInline(agent, task, options = {}) {
396
396
  });
397
397
  }, opts.timeout);
398
398
 
399
+ // Handle spawn failure (e.g. bash absent on Windows without Git Bash/WSL).
400
+ // Without an 'error' listener Node throws ENOENT as an uncaughtException and
401
+ // this Promise would never resolve (hang). pm.sh requires bash by design.
402
+ child.on('error', (err) => {
403
+ clearTimeout(timeoutId);
404
+ if (contextPath) {
405
+ fs.unlink(contextPath).catch(() => {});
406
+ }
407
+ resolve({
408
+ success: false,
409
+ output: '',
410
+ outputFile: '',
411
+ duration: Date.now() - startTime,
412
+ error: err.code === 'ENOENT'
413
+ ? 'bash nao encontrado (instale Git Bash ou WSL no Windows)'
414
+ : err.message,
415
+ });
416
+ });
417
+
399
418
  // Handle process completion
400
419
  child.on('close', async (code) => {
401
420
  clearTimeout(timeoutId);
@@ -772,7 +791,11 @@ function getSystemInfo() {
772
791
  // Get Docker version
773
792
  let dockerVersion = 'not installed';
774
793
  try {
775
- dockerVersion = execSync('docker --version 2>/dev/null', { encoding: 'utf8' }).trim();
794
+ dockerVersion = execSync('docker --version', {
795
+ encoding: 'utf8',
796
+ stdio: ['ignore', 'pipe', 'ignore'],
797
+ windowsHide: true,
798
+ }).trim();
776
799
  } catch {
777
800
  // Docker not available
778
801
  }
@@ -43,6 +43,29 @@ const DEFAULT_TIMEOUT_MS = 7200000; // 2 hours
43
43
  const CHECKPOINT_TIMEOUT_MS = 1800000; // 30 minutes
44
44
  const STATE_SAVE_INTERVAL_MS = 300000; // 5 minutes
45
45
 
46
+ /**
47
+ * Determines whether a REAL visual-terminal spawn can occur in the current environment.
48
+ *
49
+ * Combines the platform-support signal (`isSpawnerAvailable()`) with the stricter
50
+ * real-terminal signal (`detectEnvironment().supportsVisualTerminal`). The latter returns
51
+ * `false` in headless contexts (CI / SSH / Docker / VS Code integrated terminal) and `true`
52
+ * only in a native terminal. Without this second check, `isSpawnerAvailable()` alone returns
53
+ * `true` on CI / Windows-without-bash, causing `spawn('bash', [pm.sh])` to fail with ENOENT
54
+ * (test noise) plus a slow subprocess. When this returns `false`, phases skip the spawn and
55
+ * fall through to their existing "manual execution" fallback — no bash, no noise.
56
+ *
57
+ * Note: this intentionally does NOT change `TerminalSpawner.isSpawnerAvailable()` semantics
58
+ * (Conservative Default — Article XI); the hardening lives at the call-sites only.
59
+ *
60
+ * @returns {boolean} True only when a native visual terminal spawn is safe to attempt.
61
+ */
62
+ function canSpawnVisualTerminal() {
63
+ return (
64
+ TerminalSpawner.isSpawnerAvailable() &&
65
+ TerminalSpawner.detectEnvironment().supportsVisualTerminal
66
+ );
67
+ }
68
+
46
69
  /**
47
70
  * Workflow phase status
48
71
  * @enum {string}
@@ -450,6 +473,82 @@ class WorkflowExecutor {
450
473
  };
451
474
  }
452
475
 
476
+ /**
477
+ * Loads and validates an arbitrary workflow definition by path and returns it
478
+ * as a structured handoff for the agent-driven steps it describes.
479
+ *
480
+ * This is the GENERIC counterpart to {@link WorkflowExecutor#execute}, which is
481
+ * specialized for the development-cycle (it reads story metadata and runs the
482
+ * six hardcoded dev-cycle phases in-process). Handlers that drive multi-agent
483
+ * workflows — e.g. the brownfield/greenfield handlers running
484
+ * brownfield-discovery.yaml — use this entry point; the per-step work is then
485
+ * carried out by the spawned agents the workflow assigns (orchestrate-then-handoff).
486
+ *
487
+ * Validation is REAL: a missing path, a missing file, malformed YAML, or an
488
+ * empty definition each surface as an honest `{ success: false, error }`. The
489
+ * method never fabricates step output.
490
+ *
491
+ * @param {string} workflowPath - Absolute path to the workflow YAML
492
+ * @param {Object} [options] - Execution context
493
+ * @param {string} [options.projectRoot] - Project root (defaults to this.projectRoot)
494
+ * @param {Object} [options.techStack] - Detected tech stack threaded into the returned context
495
+ * @returns {Promise<Object>} `{ success, workflowPath, workflow, steps, context }`
496
+ * on success, or `{ success: false, error }` on a validation failure.
497
+ */
498
+ async executeWorkflow(workflowPath, options = {}) {
499
+ if (!workflowPath || typeof workflowPath !== 'string') {
500
+ return { success: false, error: 'workflowPath is required and must be a string' };
501
+ }
502
+
503
+ if (!fsSync.existsSync(workflowPath)) {
504
+ return { success: false, error: `Workflow file not found: ${workflowPath}` };
505
+ }
506
+
507
+ let definition;
508
+ try {
509
+ const content = await fs.readFile(workflowPath, 'utf8');
510
+ definition = yaml.load(content);
511
+ } catch (error) {
512
+ return { success: false, error: `Failed to parse workflow ${workflowPath}: ${error.message}` };
513
+ }
514
+
515
+ const workflow = definition && definition.workflow ? definition.workflow : definition;
516
+ if (!workflow || typeof workflow !== 'object') {
517
+ return { success: false, error: `Workflow definition is empty: ${workflowPath}` };
518
+ }
519
+
520
+ return {
521
+ success: true,
522
+ workflowPath,
523
+ workflow,
524
+ steps: WorkflowExecutor._extractStepIds(workflow),
525
+ context: {
526
+ projectRoot: options.projectRoot || this.projectRoot,
527
+ techStack: options.techStack || {},
528
+ },
529
+ };
530
+ }
531
+
532
+ /**
533
+ * Extracts ordered step identifiers from a workflow definition that may model
534
+ * its steps as a `sequence` list (brownfield/greenfield workflows) or a
535
+ * `phases` object map (development-cycle).
536
+ * @param {Object} workflow - The `workflow` node of a parsed definition
537
+ * @returns {string[]} Ordered step identifiers (empty array when none declared)
538
+ * @private
539
+ */
540
+ static _extractStepIds(workflow) {
541
+ if (workflow && Array.isArray(workflow.sequence)) {
542
+ return workflow.sequence.map(
543
+ (step, index) => (step && (step.step || step.id || step.name)) || `step_${index + 1}`,
544
+ );
545
+ }
546
+ if (workflow && workflow.phases && typeof workflow.phases === 'object') {
547
+ return Object.keys(workflow.phases);
548
+ }
549
+ return [];
550
+ }
551
+
453
552
  /**
454
553
  * Executes a single workflow phase
455
554
  * @param {string} phaseId - Phase identifier
@@ -641,7 +740,7 @@ class WorkflowExecutor {
641
740
  }
642
741
 
643
742
  // Use terminal spawning (Story 11.2)
644
- if (phase.spawn_in_terminal && TerminalSpawner.isSpawnerAvailable()) {
743
+ if (phase.spawn_in_terminal && canSpawnVisualTerminal()) {
645
744
  const context = {
646
745
  story: storyPath,
647
746
  files: [],
@@ -958,7 +1057,7 @@ class WorkflowExecutor {
958
1057
  this._emitAgentSpawn(agent, 'quality_gate');
959
1058
 
960
1059
  // Use terminal spawning
961
- if (phase.spawn_in_terminal && TerminalSpawner.isSpawnerAvailable()) {
1060
+ if (phase.spawn_in_terminal && canSpawnVisualTerminal()) {
962
1061
  const context = {
963
1062
  story: storyPath,
964
1063
  files: [],
@@ -1028,7 +1127,7 @@ class WorkflowExecutor {
1028
1127
  this._emitAgentSpawn(agent, 'push');
1029
1128
 
1030
1129
  // Use terminal spawning
1031
- if (phase.spawn_in_terminal && TerminalSpawner.isSpawnerAvailable()) {
1130
+ if (phase.spawn_in_terminal && canSpawnVisualTerminal()) {
1032
1131
  const context = {
1033
1132
  story: storyPath,
1034
1133
  files: [],
@@ -124,13 +124,15 @@ class FocusAreaRecommender {
124
124
 
125
125
  for (const file of changedFiles.slice(0, 20)) {
126
126
  try {
127
- // Count commits touching this file in last 30 days
128
- const commitCount = execSync(
129
- `git log --oneline --since="30 days ago" -- "${file}" 2>/dev/null | wc -l`,
130
- { encoding: 'utf8', timeout: 5000 },
131
- ).trim();
127
+ // Count commits touching this file in last 30 days. No shell pipe
128
+ // (wc -l / 2>/dev/null) — those fail on Windows cmd; count lines in JS
129
+ // and suppress stderr via stdio so it stays cross-platform.
130
+ const commitOut = execSync(
131
+ `git log --oneline --since="30 days ago" -- "${file}"`,
132
+ { encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'] },
133
+ );
132
134
 
133
- const count = parseInt(commitCount, 10) || 0;
135
+ const count = commitOut.split('\n').filter(Boolean).length;
134
136
 
135
137
  if (count >= 5) {
136
138
  insights.hotspots.push({
@@ -140,11 +142,13 @@ class FocusAreaRecommender {
140
142
  });
141
143
  }
142
144
 
143
- // Get unique contributors for this file
144
- const authors = execSync(
145
- `git log --format="%aN" --since="30 days ago" -- "${file}" 2>/dev/null | sort -u`,
146
- { encoding: 'utf8', timeout: 5000 },
147
- ).trim().split('\n').filter(Boolean);
145
+ // Get unique contributors for this file. Dedup in JS via Set instead of
146
+ // a `| sort -u` shell pipe (unavailable on Windows cmd).
147
+ const authorsOut = execSync(
148
+ `git log --format="%aN" --since="30 days ago" -- "${file}"`,
149
+ { encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'] },
150
+ );
151
+ const authors = [...new Set(authorsOut.split('\n').map((s) => s.trim()).filter(Boolean))];
148
152
 
149
153
  for (const author of authors) {
150
154
  insights.contributors.set(author, (insights.contributors.get(author) || 0) + 1);
@@ -23,8 +23,9 @@ const SCAN_SOURCES = [
23
23
  category: 'task',
24
24
  taskFormat: 'TASK-FORMAT-V1',
25
25
  subcategoryExtractor: (filePath) => {
26
- const parts = filePath.split('/');
27
- const filename = parts[parts.length - 1];
26
+ // path.basename is OS-agnostic; a raw glob result on Windows uses '\\',
27
+ // so split('/') would return the whole path and corrupt the subcategory.
28
+ const filename = path.basename(filePath);
28
29
  // Extract agent prefix (e.g., dev-, qa-, po-)
29
30
  const prefixMatch = filename.match(/^([a-z]+)-/);
30
31
  if (prefixMatch) {
@@ -20,6 +20,7 @@ const path = require('path');
20
20
  const ROMAN_TO_ARABIC = {
21
21
  'I': 1, 'II': 2, 'III': 3, 'IV': 4, 'V': 5,
22
22
  'VI': 6, 'VII': 7, 'VIII': 8, 'IX': 9, 'X': 10,
23
+ 'XI': 11,
23
24
  };
24
25
 
25
26
  /**
@@ -22,6 +22,28 @@ const path = require('path');
22
22
 
23
23
  const IS_WINDOWS = process.platform === 'win32';
24
24
 
25
+ // On Windows the AV scanner, Windows Search indexer, or a concurrent reader can
26
+ // hold a transient lock on the target, making unlink/rename throw EPERM/EBUSY
27
+ // where POSIX would succeed. A short bounded retry clears virtually all of these.
28
+ const TRANSIENT_LOCK_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);
29
+
30
+ function sleepSync(ms) {
31
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
32
+ }
33
+
34
+ function retrySync(fn, retries = 3, delayMs = 120) {
35
+ for (let attempt = 0; ; attempt++) {
36
+ try {
37
+ return fn();
38
+ } catch (err) {
39
+ if (!TRANSIENT_LOCK_CODES.has(err.code) || attempt >= retries) {
40
+ throw err;
41
+ }
42
+ sleepSync(delayMs * (attempt + 1));
43
+ }
44
+ }
45
+ }
46
+
25
47
  /**
26
48
  * Write data to a file atomically.
27
49
  *
@@ -49,18 +71,20 @@ function atomicWriteSync(filePath, data, encoding = 'utf8') {
49
71
 
50
72
  // Step 2: On Windows, unlink target first (rename won't overwrite)
51
73
  if (IS_WINDOWS) {
52
- try {
53
- fs.unlinkSync(filePath);
54
- } catch (err) {
55
- if (err.code !== 'ENOENT') {
56
- throw err;
74
+ retrySync(() => {
75
+ try {
76
+ fs.unlinkSync(filePath);
77
+ } catch (err) {
78
+ if (err.code !== 'ENOENT') {
79
+ throw err;
80
+ }
81
+ // ENOENT = target doesn't exist yet, that's fine
57
82
  }
58
- // ENOENT = target doesn't exist yet, that's fine
59
- }
83
+ });
60
84
  }
61
85
 
62
- // Step 3: Atomic rename
63
- fs.renameSync(tmpPath, filePath);
86
+ // Step 3: Atomic rename (retried for transient Windows locks)
87
+ retrySync(() => fs.renameSync(tmpPath, filePath));
64
88
  } catch (error) {
65
89
  // Clean up tmp file on failure
66
90
  try {
@@ -76,5 +100,6 @@ function atomicWriteSync(filePath, data, encoding = 'utf8') {
76
100
 
77
101
  module.exports = {
78
102
  atomicWriteSync,
103
+ retrySync,
79
104
  };
80
105
 
@@ -310,7 +310,11 @@ ideSync:
310
310
  enabled: false
311
311
  path: .codex/agents
312
312
  format: full-markdown-yaml
313
- redirects: {}
313
+ redirects:
314
+ # Master alias: o id-fonte canônico é snps-orqx; sinapse-orqx aponta para ele
315
+ # no espelho de dogfood (.claude/). No install o command-generator gera ambos
316
+ # como entry points full do Imperator — isto cobre só a paridade do repo.
317
+ sinapse-orqx: snps-orqx
314
318
  validation:
315
319
  strictMode: true
316
320
  failOnDrift: true
@@ -26,7 +26,7 @@ function detectToolSearch() {
26
26
  // Check Claude Code cached features for tool search availability
27
27
  const claudeJsonPath = path.join(os.homedir(), '.claude.json');
28
28
  try {
29
- const config = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf8'));
29
+ const config = JSON.parse(fs.readFileSync(claudeJsonPath, 'utf8').replace(/^\uFEFF/, ''));
30
30
  const features = config.cachedGrowthBookFeatures || {};
31
31
  return {
32
32
  available: features.tengu_mcp_tool_search === true,
@@ -54,7 +54,7 @@ function detectDeferLoading() {
54
54
  function detectProjectMcps() {
55
55
  const mcpJsonPath = path.join(PROJECT_ROOT, '.mcp.json');
56
56
  try {
57
- const config = JSON.parse(fs.readFileSync(mcpJsonPath, 'utf8'));
57
+ const config = JSON.parse(fs.readFileSync(mcpJsonPath, 'utf8').replace(/^\uFEFF/, ''));
58
58
  const servers = config.mcpServers || {};
59
59
  return Object.entries(servers).map(([name, cfg]) => ({
60
60
  name,
@@ -96,7 +96,7 @@ function detectGlobalMcps() {
96
96
  // Detection: check ~/.claude/settings.json or known conventions
97
97
  const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
98
98
  try {
99
- const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
99
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8').replace(/^\uFEFF/, ''));
100
100
  if (settings.mcpServers) {
101
101
  for (const [name, cfg] of Object.entries(settings.mcpServers)) {
102
102
  servers.push({