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.
- package/.claude/hooks/doc-first-gate.cjs +156 -0
- package/.claude/hooks/enforce-story-gate.cjs +6 -2
- package/.claude/rules/documentation-first.md +6 -0
- package/.claude/rules/hook-governance.md +1 -0
- package/.sinapse-ai/constitution.md +3 -3
- package/.sinapse-ai/core/atlas/atlas-data.js +278 -0
- package/.sinapse-ai/core/atlas/flows-pt.js +253 -0
- package/.sinapse-ai/core/atlas/flows.js +266 -0
- package/.sinapse-ai/core/atlas/index.js +62 -0
- package/.sinapse-ai/core/atlas/render-html.js +216 -0
- package/.sinapse-ai/core/atlas/render-markdown.js +313 -0
- package/.sinapse-ai/core/atlas/render-research-card.js +164 -0
- package/.sinapse-ai/core/code-intel/registry-syncer.js +5 -3
- package/.sinapse-ai/core/doctor/checks/agent-memory.js +7 -5
- package/.sinapse-ai/core/doctor/checks/claude-md.js +13 -0
- package/.sinapse-ai/core/doctor/checks/constitution-consistency.js +1 -0
- package/.sinapse-ai/core/doctor/checks/hooks-claude-count.js +11 -0
- package/.sinapse-ai/core/doctor/checks/settings-json.js +16 -2
- package/.sinapse-ai/core/doctor/index.js +27 -0
- package/.sinapse-ai/core/execution/build-orchestrator.js +192 -8
- package/.sinapse-ai/core/external-executors/delegate-cli.js +6 -2
- package/.sinapse-ai/core/health-check/checks/project/constitution-consistency.js +2 -1
- package/.sinapse-ai/core/ideation/ideation-engine.js +10 -8
- package/.sinapse-ai/core/mcp/config-migrator.js +8 -5
- package/.sinapse-ai/core/mcp/global-config-manager.js +4 -1
- package/.sinapse-ai/core/mcp/symlink-manager.js +6 -3
- package/.sinapse-ai/core/orchestration/brownfield-handler.js +5 -4
- package/.sinapse-ai/core/orchestration/build-command.js +136 -0
- package/.sinapse-ai/core/orchestration/doc-first-resolver.js +322 -0
- package/.sinapse-ai/core/orchestration/executors/epic-4-executor.js +3 -0
- package/.sinapse-ai/core/orchestration/gate-evaluator.js +58 -9
- package/.sinapse-ai/core/orchestration/route-command.js +97 -0
- package/.sinapse-ai/core/orchestration/session-state.js +19 -2
- package/.sinapse-ai/core/orchestration/terminal-spawner.js +24 -1
- package/.sinapse-ai/core/orchestration/workflow-executor.js +102 -3
- package/.sinapse-ai/core/quality-gates/focus-area-recommender.js +15 -11
- package/.sinapse-ai/core/registry/build-registry.js +3 -2
- package/.sinapse-ai/core/synapse/scripts/generate-constitution.js +1 -0
- package/.sinapse-ai/core/synapse/utils/atomic-write.js +34 -9
- package/.sinapse-ai/core-config.yaml +5 -1
- package/.sinapse-ai/data/capability-detection.js +3 -3
- package/.sinapse-ai/data/entity-registry.yaml +288 -90
- package/.sinapse-ai/data/mcp-discipline.js +1 -1
- package/.sinapse-ai/data/mcp-tool-examples.yaml +8 -8
- package/.sinapse-ai/data/tok2-validation.js +1 -1
- package/.sinapse-ai/data/tool-registry.yaml +4 -3
- package/.sinapse-ai/development/agents/snps-orqx.md +14 -5
- package/.sinapse-ai/development/scripts/migrate-task-to-v2.js +1 -1
- package/.sinapse-ai/development/scripts/validate-task-v2.js +67 -4
- package/.sinapse-ai/development/tasks/advanced-elicitation.md +3 -3
- package/.sinapse-ai/development/tasks/analyst-facilitate-brainstorming.md +3 -3
- package/.sinapse-ai/development/tasks/analyze-framework.md +1 -8
- package/.sinapse-ai/development/tasks/analyze-performance.md +1 -8
- package/.sinapse-ai/development/tasks/apply-qa-fixes.md +3 -3
- package/.sinapse-ai/development/tasks/architect-analyze-impact.md +3 -3
- package/.sinapse-ai/development/tasks/audit-codebase.md +1 -8
- package/.sinapse-ai/development/tasks/audit-tailwind-config.md +1 -4
- package/.sinapse-ai/development/tasks/audit-utilities.md +1 -8
- package/.sinapse-ai/development/tasks/bootstrap-shadcn-library.md +3 -3
- package/.sinapse-ai/development/tasks/brownfield-create-epic.md +3 -3
- package/.sinapse-ai/development/tasks/brownfield-create-story.md +3 -3
- package/.sinapse-ai/development/tasks/build-component.md +2 -5
- package/.sinapse-ai/development/tasks/calculate-roi.md +3 -3
- package/.sinapse-ai/development/tasks/ci-cd-configuration.md +1 -1
- package/.sinapse-ai/development/tasks/cleanup-utilities.md +3 -3
- package/.sinapse-ai/development/tasks/collaborative-edit.md +3 -3
- package/.sinapse-ai/development/tasks/compose-molecule.md +2 -5
- package/.sinapse-ai/development/tasks/consolidate-patterns.md +3 -3
- package/.sinapse-ai/development/tasks/correct-course.md +3 -3
- package/.sinapse-ai/development/tasks/create-brownfield-story.md +2 -5
- package/.sinapse-ai/development/tasks/create-deep-research-prompt.md +2 -5
- package/.sinapse-ai/development/tasks/create-doc.md +3 -6
- package/.sinapse-ai/development/tasks/create-next-story.md +4 -8
- package/.sinapse-ai/development/tasks/create-suite.md +2 -5
- package/.sinapse-ai/development/tasks/create-task.md +2 -5
- package/.sinapse-ai/development/tasks/create-workflow.md +2 -5
- package/.sinapse-ai/development/tasks/db-analyze-hotpaths.md +1 -8
- package/.sinapse-ai/development/tasks/db-apply-migration.md +1 -8
- package/.sinapse-ai/development/tasks/db-bootstrap.md +1 -8
- package/.sinapse-ai/development/tasks/db-domain-modeling.md +1 -8
- package/.sinapse-ai/development/tasks/db-dry-run.md +1 -8
- package/.sinapse-ai/development/tasks/db-env-check.md +1 -8
- package/.sinapse-ai/development/tasks/db-explain.md +1 -8
- package/.sinapse-ai/development/tasks/db-impersonate.md +1 -8
- package/.sinapse-ai/development/tasks/db-load-csv.md +1 -8
- package/.sinapse-ai/development/tasks/db-policy-apply.md +1 -8
- package/.sinapse-ai/development/tasks/db-rls-audit.md +1 -8
- package/.sinapse-ai/development/tasks/db-rollback.md +1 -8
- package/.sinapse-ai/development/tasks/db-run-sql.md +1 -8
- package/.sinapse-ai/development/tasks/db-schema-audit.md +1 -8
- package/.sinapse-ai/development/tasks/db-seed.md +1 -8
- package/.sinapse-ai/development/tasks/db-smoke-test.md +1 -8
- package/.sinapse-ai/development/tasks/db-snapshot.md +1 -8
- package/.sinapse-ai/development/tasks/db-squad-integration.md +1 -8
- package/.sinapse-ai/development/tasks/db-supabase-setup.md +1 -8
- package/.sinapse-ai/development/tasks/db-verify-order.md +1 -8
- package/.sinapse-ai/development/tasks/deprecate-component.md +3 -3
- package/.sinapse-ai/development/tasks/dev-apply-qa-fixes.md +3 -3
- package/.sinapse-ai/development/tasks/dev-backlog-debt.md +3 -3
- package/.sinapse-ai/development/tasks/dev-develop-story.md +1 -1
- package/.sinapse-ai/development/tasks/dev-improve-code-quality.md +3 -3
- package/.sinapse-ai/development/tasks/dev-optimize-performance.md +3 -3
- package/.sinapse-ai/development/tasks/dev-suggest-refactoring.md +3 -3
- package/.sinapse-ai/development/tasks/dev-validate-next-story.md +3 -3
- package/.sinapse-ai/development/tasks/document-project.md +3 -3
- package/.sinapse-ai/development/tasks/environment-bootstrap.md +0 -4
- package/.sinapse-ai/development/tasks/execute-checklist.md +3 -3
- package/.sinapse-ai/development/tasks/export-design-tokens-dtcg.md +3 -3
- package/.sinapse-ai/development/tasks/extend-pattern.md +1 -8
- package/.sinapse-ai/development/tasks/extract-tokens.md +3 -3
- package/.sinapse-ai/development/tasks/facilitate-brainstorming-session.md +1 -1
- package/.sinapse-ai/development/tasks/generate-ai-frontend-prompt.md +2 -5
- package/.sinapse-ai/development/tasks/generate-documentation.md +2 -5
- package/.sinapse-ai/development/tasks/generate-migration-strategy.md +2 -5
- package/.sinapse-ai/development/tasks/generate-shock-report.md +2 -5
- package/.sinapse-ai/development/tasks/github-devops-github-pr-automation.md +3 -3
- package/.sinapse-ai/development/tasks/github-devops-repository-cleanup.md +3 -3
- package/.sinapse-ai/development/tasks/github-devops-version-management.md +3 -3
- package/.sinapse-ai/development/tasks/improve-self.md +1 -16
- package/.sinapse-ai/development/tasks/index-docs.md +1 -4
- package/.sinapse-ai/development/tasks/init-project-status.md +1 -7
- package/.sinapse-ai/development/tasks/integrate-squad.md +3 -3
- package/.sinapse-ai/development/tasks/kb-mode-interaction.md +3 -3
- package/.sinapse-ai/development/tasks/learn-patterns.md +3 -3
- package/.sinapse-ai/development/tasks/modify-agent.md +1 -8
- package/.sinapse-ai/development/tasks/modify-task.md +1 -8
- package/.sinapse-ai/development/tasks/modify-workflow.md +1 -8
- package/.sinapse-ai/development/tasks/po-backlog-add.md +3 -3
- package/.sinapse-ai/development/tasks/po-manage-story-backlog.md +3 -3
- package/.sinapse-ai/development/tasks/po-pull-story-from-clickup.md +3 -3
- package/.sinapse-ai/development/tasks/po-pull-story.md +3 -3
- package/.sinapse-ai/development/tasks/po-stories-index.md +3 -3
- package/.sinapse-ai/development/tasks/po-sync-story-to-clickup.md +3 -3
- package/.sinapse-ai/development/tasks/po-sync-story.md +3 -3
- package/.sinapse-ai/development/tasks/pr-automation.md +1 -1
- package/.sinapse-ai/development/tasks/propose-modification.md +3 -3
- package/.sinapse-ai/development/tasks/qa-backlog-add-followup.md +1 -8
- package/.sinapse-ai/development/tasks/qa-create-fix-request.md +1 -4
- package/.sinapse-ai/development/tasks/qa-gate.md +1 -8
- package/.sinapse-ai/development/tasks/qa-generate-tests.md +1 -8
- package/.sinapse-ai/development/tasks/qa-nfr-assess.md +1 -8
- package/.sinapse-ai/development/tasks/qa-review-proposal.md +1 -8
- package/.sinapse-ai/development/tasks/qa-review-story.md +1 -8
- package/.sinapse-ai/development/tasks/qa-risk-profile.md +1 -8
- package/.sinapse-ai/development/tasks/qa-run-tests.md +1 -8
- package/.sinapse-ai/development/tasks/qa-test-design.md +1 -8
- package/.sinapse-ai/development/tasks/qa-trace-requirements.md +1 -8
- package/.sinapse-ai/development/tasks/release-management.md +1 -1
- package/.sinapse-ai/development/tasks/security-audit.md +1 -4
- package/.sinapse-ai/development/tasks/security-scan.md +1 -4
- package/.sinapse-ai/development/tasks/setup-database.md +2 -11
- package/.sinapse-ai/development/tasks/setup-design-system.md +2 -11
- package/.sinapse-ai/development/tasks/shard-doc.md +3 -3
- package/.sinapse-ai/development/tasks/sm-create-next-story.md +3 -3
- package/.sinapse-ai/development/tasks/spec-gather-requirements.md +11 -0
- package/.sinapse-ai/development/tasks/sync-documentation.md +1 -6
- package/.sinapse-ai/development/tasks/tailwind-upgrade.md +3 -3
- package/.sinapse-ai/development/tasks/test-as-user.md +3 -3
- package/.sinapse-ai/development/tasks/undo-last.md +2 -5
- package/.sinapse-ai/development/tasks/update-manifest.md +1 -8
- package/.sinapse-ai/development/tasks/ux-create-wireframe.md +1 -1
- package/.sinapse-ai/development/tasks/ux-ds-scan-artifact.md +3 -3
- package/.sinapse-ai/development/tasks/ux-user-research.md +3 -3
- package/.sinapse-ai/development/tasks/validate-next-story.md +1 -8
- package/.sinapse-ai/development/templates/approval-table.md +106 -0
- package/.sinapse-ai/development/templates/chrome-brain/scripts/chrome-ensure.cjs +1 -1
- package/.sinapse-ai/development/workflows/spec-pipeline.yaml +1 -0
- package/.sinapse-ai/git-hooks/post-commit +0 -0
- package/.sinapse-ai/git-hooks/pre-commit +0 -0
- package/.sinapse-ai/git-hooks/pre-push +0 -0
- package/.sinapse-ai/infrastructure/scripts/changelog-generator.js +5 -1
- package/.sinapse-ai/infrastructure/scripts/pattern-extractor.js +11 -2
- package/.sinapse-ai/infrastructure/scripts/test-utilities.js +34 -13
- package/.sinapse-ai/infrastructure/scripts/usage-analytics.js +9 -5
- package/.sinapse-ai/infrastructure/scripts/validate-claude-integration.js +10 -2
- package/.sinapse-ai/install-manifest.yaml +364 -320
- package/.sinapse-ai/lib/build.json +1 -0
- package/.sinapse-ai/product/templates/personalized-task-template-v2.md +4 -2
- package/.sinapse-ai/product/templates/prd-tmpl.yaml +6 -2
- package/.sinapse-ai/product/templates/statusline/statusline-script.js +7 -3
- package/CHANGELOG.md +85 -7
- package/README.en.md +5 -5
- package/README.md +5 -5
- package/bin/cli.js +1 -1
- package/bin/commands/install.js +288 -114
- package/bin/commands/local.js +11 -0
- package/bin/lib/command-generator.js +31 -2
- package/bin/sinapse.js +121 -0
- package/docs/README.md +1 -1
- package/docs/agent-reference-guide.md +1 -1
- package/docs/community/README-community-snippet-core.md +1 -1
- package/docs/community/README-community-snippet-mcp.md +1 -1
- package/docs/community/README-community-snippet-squads.md +1 -1
- package/docs/examples/quickstart-recording.md +1 -1
- package/docs/framework/README.md +1 -1
- package/docs/framework/architecture-overview.md +1 -0
- package/docs/framework/atlas/OPERATING-ATLAS.md +537 -0
- package/docs/framework/atlas/README.md +34 -0
- package/docs/framework/atlas/atlas-data.json +2810 -0
- package/docs/framework/atlas/atlas.html +392 -0
- package/docs/framework/coding-standards.md +1 -1
- package/docs/framework/core-architecture.md +1 -1
- package/docs/framework/guiding-principles.md +1 -1
- package/docs/framework/source-tree.md +1 -1
- package/docs/framework/tech-stack.md +1 -1
- package/docs/framework/versioning-and-releases.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/guides/agent-reference.md +1 -1
- package/docs/guides/agent-selection-guide.md +1 -1
- package/docs/guides/api-reference.md +1 -1
- package/docs/guides/contextual-greeting-system-guide.md +1 -1
- package/docs/guides/contributing-squads.md +1 -1
- package/docs/guides/development-setup.md +1 -1
- package/docs/guides/git-workflow-guide.md +1 -1
- package/docs/guides/installation-troubleshooting.md +1 -1
- package/docs/guides/llm-routing.md +1 -1
- package/docs/guides/mcp-global-setup.md +1 -1
- package/docs/guides/meta-agent-commands.md +1 -1
- package/docs/guides/project-status-feature.md +1 -1
- package/docs/guides/quality-dashboard.md +1 -1
- package/docs/guides/quality-gates.md +1 -1
- package/docs/guides/security-hardening.md +1 -1
- package/docs/guides/service-discovery.md +19 -22
- package/docs/guides/squad-examples/README.md +1 -1
- package/docs/guides/squad-migration.md +1 -1
- package/docs/guides/squads-guide.md +1 -1
- package/docs/guides/squads-overview.md +10 -13
- package/docs/guides/template-engine-v2.md +1 -1
- package/docs/guides/testing-guide.md +1 -1
- package/docs/guides/user-guide.md +30 -26
- package/docs/installation/README.md +3 -3
- package/docs/installation/faq.md +1 -1
- package/docs/installation/linux.md +2 -2
- package/docs/installation/macos.md +1 -1
- package/docs/installation/npx-install.md +1 -1
- package/docs/installation/troubleshooting.md +1 -1
- package/docs/installation/uninstallation.md +1 -1
- package/docs/installation/v4-quick-start.md +1 -1
- package/docs/installation/windows.md +2 -2
- package/docs/pt/CHANGELOG.md +1 -1
- package/docs/pt/DOCUMENTATION-ROADMAP.md +1 -1
- package/docs/pt/ENVIRONMENT.md +1 -1
- package/docs/pt/FEATURE_PROCESS.md +2 -2
- package/docs/pt/GUIDING-PRINCIPLES.md +2 -2
- package/docs/pt/agent-reference-guide.md +3 -3
- package/docs/pt/architecture/ARCHITECTURE-INDEX.md +2 -2
- package/docs/pt/architecture/ade-architecture.md +1 -1
- package/docs/pt/architecture/agent-config-audit.md +1 -1
- package/docs/pt/architecture/agent-responsibility-matrix.md +1 -1
- package/docs/pt/architecture/agent-tool-integration-guide.md +1 -1
- package/docs/pt/architecture/ci-cd.md +1 -1
- package/docs/pt/architecture/coding-standards.md +1 -1
- package/docs/pt/architecture/contribution-workflow-research.md +1 -1
- package/docs/pt/architecture/dashboard-architecture.md +1 -1
- package/docs/pt/architecture/dashboard-realtime.md +1 -1
- package/docs/pt/architecture/hcs-check-specifications.md +1 -1
- package/docs/pt/architecture/hcs-execution-modes.md +1 -1
- package/docs/pt/architecture/hcs-self-healing-spec.md +1 -1
- package/docs/pt/architecture/high-level-architecture.md +1 -1
- package/docs/pt/architecture/introduction.md +1 -1
- package/docs/pt/architecture/mcp-api-keys-management.md +3 -3
- package/docs/pt/architecture/mcp-system-diagrams.md +1 -1
- package/docs/pt/architecture/module-system.md +4 -4
- package/docs/pt/architecture/multi-repo-strategy.md +2 -2
- package/docs/pt/architecture/source-tree.md +1 -1
- package/docs/pt/architecture/squad-improvement-analysis.md +1 -1
- package/docs/pt/architecture/squad-improvement-recommended-approach.md +1 -1
- package/docs/pt/architecture/tech-stack.md +1 -1
- package/docs/pt/architecture/utility-integration-guide.md +1 -1
- package/docs/pt/code-of-conduct.md +1 -1
- package/docs/pt/community/README-community-snippet-core.md +1 -1
- package/docs/pt/community/README-community-snippet-mcp.md +2 -2
- package/docs/pt/contributing.md +7 -7
- package/docs/pt/core-architecture.md +1 -1
- package/docs/pt/docker-mcp-setup.md +1 -1
- package/docs/pt/framework/README.md +1 -1
- package/docs/pt/framework/coding-standards.md +1 -1
- package/docs/pt/framework/source-tree.md +1 -1
- package/docs/pt/framework/tech-stack.md +1 -1
- package/docs/pt/getting-started.md +1 -1
- package/docs/pt/git-workflow-guide.md +1 -1
- package/docs/pt/guides/README.md +3 -3
- package/docs/pt/guides/agent-selection-guide.md +2 -2
- package/docs/pt/guides/api-reference.md +1 -1
- package/docs/pt/guides/contextual-greeting-system-guide.md +1 -1
- package/docs/pt/guides/contributing-squads.md +1 -1
- package/docs/pt/guides/development-setup.md +1 -1
- package/docs/pt/guides/installation-troubleshooting.md +1 -1
- package/docs/pt/guides/llm-routing.md +1 -1
- package/docs/pt/guides/mcp/desktop-commander.md +1 -1
- package/docs/pt/guides/mcp/docker-gateway-tutorial.md +1 -1
- package/docs/pt/guides/mcp-global-setup.md +1 -1
- package/docs/pt/guides/project-status-feature.md +1 -1
- package/docs/pt/guides/quality-dashboard.md +1 -1
- package/docs/pt/guides/quality-gates.md +1 -1
- package/docs/pt/guides/security-hardening.md +2 -2
- package/docs/pt/guides/service-discovery.md +19 -22
- package/docs/pt/guides/squad-examples/README.md +1 -1
- package/docs/pt/guides/squad-migration.md +1 -1
- package/docs/pt/guides/squads-guide.md +1 -1
- package/docs/pt/guides/squads-overview.md +11 -13
- package/docs/pt/guides/template-engine-v2.md +1 -1
- package/docs/pt/guides/testing-guide.md +3 -3
- package/docs/pt/guides/user-guide.md +30 -26
- package/docs/pt/guides/workflows-guide.md +1 -1
- package/docs/pt/how-to-contribute-with-pull-requests.md +1 -1
- package/docs/pt/ide-integration.md +2 -2
- package/docs/pt/installation/README.md +1 -1
- package/docs/pt/installation/faq.md +1 -1
- package/docs/pt/installation/linux.md +1 -1
- package/docs/pt/installation/macos.md +1 -1
- package/docs/pt/installation/troubleshooting.md +1 -1
- package/docs/pt/installation/v4-quick-start.md +1 -1
- package/docs/pt/installation/windows.md +1 -1
- package/docs/pt/meta-agent-commands.md +1 -1
- package/docs/pt/migration-guide.md +1 -1
- package/docs/pt/npx-install.md +1 -1
- package/docs/pt/performance-tuning-guide.md +1 -1
- package/docs/pt/platforms/claude-code.md +2 -2
- package/docs/pt/roadmap.md +2 -2
- package/docs/pt/security-best-practices.md +2 -2
- package/docs/pt/security.md +1 -1
- package/docs/pt/sinapse-nomenclature-specification.md +1 -1
- package/docs/pt/troubleshooting.md +1 -1
- package/docs/pt/uninstallation.md +1 -1
- package/docs/pt/versioning-and-releases.md +1 -1
- package/docs/security/overview.md +1 -1
- package/docs/security/security-best-practices.md +2 -2
- package/docs/sinapse-workflows/README.md +1 -1
- package/package.json +2 -1
- package/packages/installer/package.json +1 -0
- package/packages/installer/src/wizard/feedback.js +18 -2
- package/packages/installer/src/wizard/i18n.js +78 -0
- package/packages/installer/src/wizard/ide-config-generator.js +14 -9
- package/packages/installer/src/wizard/index.js +16 -16
- package/packages/installer/src/wizard/validation/report-generator.js +22 -21
- package/packages/installer/src/wizard/validation/troubleshooting-system.js +19 -13
- package/scripts/gen-agent-badges.js +1 -1
- package/scripts/install-chrome-brain.sh +2 -2
- package/scripts/package-synapse.js +14 -5
- package/scripts/prepare-hooks.js +19 -0
- package/scripts/validate-agent-codenames.js +174 -0
- package/scripts/validate-all.js +1 -0
- package/scripts/validate-no-personal-leaks.js +24 -9
- package/sinapse/agents/sinapse-orqx.md +5 -5
- package/sinapse/agents/snps-orqx.md +5 -5
- package/squads/squad-brand/agents/brand-creative-engineer.md +5 -5
- package/squads/squad-brand/squad.yaml +6 -6
- package/squads/squad-content/agents/content-engineer.md +7 -7
- package/squads/squad-content/squad.yaml +5 -5
- package/squads/squad-copy/knowledge-base/consequence-headline-patterns.md +2 -2
- package/squads/squad-courses/agents/production-director.md +5 -5
- package/squads/squad-courses/squad.yaml +1 -1
- 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
|
|
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
|
|
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
|
|
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 &&
|
|
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 &&
|
|
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 &&
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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 =
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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) {
|
|
@@ -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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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({
|