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.
- package/.claude/hooks/mind-clone-governance.py +212 -212
- package/.claude/hooks/read-protection.py +152 -152
- package/.claude/hooks/slug-validation.py +175 -175
- package/.claude/hooks/sql-governance.py +183 -183
- package/.claude/rules/documentation-first.md +1 -1
- package/.claude/rules/hook-governance.md +1 -1
- package/.claude/rules/mandatory-delegation.md +1 -1
- package/.claude/rules/project-intelligence.md +1 -1
- package/.codex/agents/analyst.md +4 -371
- package/.codex/agents/animations-orqx.md +4 -57
- package/.codex/agents/architect.md +4 -560
- package/.codex/agents/brand-orqx.md +4 -95
- package/.codex/agents/claude-mastery-chief.md +4 -0
- package/.codex/agents/cloning-orqx.md +4 -70
- package/.codex/agents/commercial-orqx.md +4 -67
- package/.codex/agents/config-engineer.md +2 -2
- package/.codex/agents/content-orqx.md +4 -77
- package/.codex/agents/copy-orqx.md +4 -65
- package/.codex/agents/cost-optimizer.md +4 -0
- package/.codex/agents/council-orqx.md +4 -68
- package/.codex/agents/courses-orqx.md +4 -64
- package/.codex/agents/cro-persuasion.md +4 -0
- package/.codex/agents/cyber-orqx.md +4 -67
- package/.codex/agents/data-engineer.md +4 -542
- package/.codex/agents/design-orqx.md +4 -65
- package/.codex/agents/design-system.md +4 -210
- package/.codex/agents/developer.md +4 -666
- package/.codex/agents/devops.md +4 -668
- package/.codex/agents/finance-orqx.md +4 -57
- package/.codex/agents/fiscal-compliance-br.md +4 -0
- package/.codex/agents/forecast-strategist.md +4 -0
- package/.codex/agents/growth-orqx.md +4 -75
- package/.codex/agents/hooks-architect.md +2 -2
- package/.codex/agents/mcp-integrator.md +2 -2
- package/.codex/agents/paidmedia-orqx.md +4 -67
- package/.codex/agents/platform-aesthetic-director.md +4 -0
- package/.codex/agents/premium-packaging-strategist.md +4 -0
- package/.codex/agents/product-lead.md +4 -371
- package/.codex/agents/product-orqx.md +4 -57
- package/.codex/agents/product-surface-director.md +4 -0
- package/.codex/agents/project-integrator.md +2 -2
- package/.codex/agents/project-lead.md +4 -414
- package/.codex/agents/quality-gate.md +4 -547
- package/.codex/agents/research-orqx.md +4 -67
- package/.codex/agents/roadmap-sentinel.md +2 -2
- package/.codex/agents/skill-craftsman.md +2 -2
- package/.codex/agents/snps-orqx.md +4 -684
- package/.codex/agents/sop-extractor.md +4 -61
- package/.codex/agents/sprint-lead.md +4 -324
- package/.codex/agents/squad-creator.md +4 -402
- package/.codex/agents/storytelling-orqx.md +4 -65
- package/.codex/agents/swarm-orqx.md +4 -64
- package/.codex/agents/ux-design-expert.md +4 -532
- package/.codex/agents/ux-designer.md +4 -124
- package/.codex/command-registry.json +9 -9
- package/.codex/delegation-matrix.json +375 -839
- package/.codex/delegation-parity.json +658 -0
- package/.codex/handoff-packet.parity.schema.json +148 -0
- package/.codex/handoff-packet.template.json +26 -0
- package/.codex/instructions.md +8 -8
- package/.codex/scripts/resolve-codex-agent.js +482 -0
- package/.codex/scripts/resolve-codex-command.js +75 -12
- package/.codex/scripts/resolve-codex-delegation.js +131 -92
- package/.codex/skills/sinapse-claude/SKILL.md +3 -3
- package/.codex/skills/sinapse-po/SKILL.md +1 -1
- package/.codex/tasks/resolve-sinapse-conflict.md +1 -1
- package/.sinapse-ai/constitution.md +5 -5
- package/.sinapse-ai/core/doctor/checks/git-hooks.js +163 -19
- package/.sinapse-ai/core/events/dashboard-emitter.js +30 -9
- package/.sinapse-ai/core/execution/subagent-dispatcher.js +1 -1
- package/.sinapse-ai/core/synapse/engine.js +15 -0
- package/.sinapse-ai/core/ui/observability-panel.js +240 -0
- package/.sinapse-ai/core-config.yaml +0 -20
- package/.sinapse-ai/data/entity-registry.yaml +185 -236
- package/.sinapse-ai/development/agents/snps-orqx.md +16 -26
- package/.sinapse-ai/development/tasks/build-autonomous.md +11 -1
- package/.sinapse-ai/development/tasks/build-resume.md +8 -0
- package/.sinapse-ai/development/tasks/build-status.md +8 -0
- package/.sinapse-ai/development/tasks/build.md +8 -0
- package/.sinapse-ai/development/tasks/cleanup-worktrees.md +8 -1
- package/.sinapse-ai/development/tasks/gotcha.md +8 -0
- package/.sinapse-ai/development/tasks/gotchas.md +8 -0
- package/.sinapse-ai/development/tasks/ids-health.md +14 -6
- package/.sinapse-ai/development/tasks/list-mcps.md +15 -0
- package/.sinapse-ai/development/tasks/merge-worktree.md +8 -1
- package/.sinapse-ai/development/tasks/qa-review-build.md +18 -0
- package/.sinapse-ai/development/tasks/remove-mcp.md +8 -1
- package/.sinapse-ai/development/tasks/validate-agents.md +26 -14
- package/.sinapse-ai/development/templates/service-template/README.md.hbs +159 -159
- package/.sinapse-ai/development/templates/service-template/__tests__/index.test.ts.hbs +238 -238
- package/.sinapse-ai/development/templates/service-template/client.ts.hbs +404 -404
- package/.sinapse-ai/development/templates/service-template/errors.ts.hbs +183 -183
- package/.sinapse-ai/development/templates/service-template/index.ts.hbs +121 -121
- package/.sinapse-ai/development/templates/service-template/package.json.hbs +88 -88
- package/.sinapse-ai/development/templates/service-template/types.ts.hbs +146 -146
- package/.sinapse-ai/development/templates/squad-template/LICENSE +22 -22
- package/.sinapse-ai/git-hooks/lib/framework-guard.js +258 -0
- package/.sinapse-ai/git-hooks/lib/secret-scanner-core.js +355 -0
- package/.sinapse-ai/git-hooks/lib/staged-secret-scan.js +179 -0
- package/.sinapse-ai/git-hooks/lib/staged-sql-guard.js +204 -0
- package/.sinapse-ai/git-hooks/post-commit +28 -0
- package/.sinapse-ai/git-hooks/pre-commit +81 -0
- package/.sinapse-ai/git-hooks/pre-push +83 -0
- package/.sinapse-ai/hooks/ids-post-commit.js +13 -11
- package/.sinapse-ai/hooks/ids-pre-push.js +9 -7
- package/.sinapse-ai/infrastructure/scripts/codex-parity/resolve.js +161 -0
- package/.sinapse-ai/infrastructure/scripts/dashboard-status-writer.js +6 -2
- package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +65 -68
- package/.sinapse-ai/infrastructure/scripts/sync-codex-local-first.js +156 -1
- package/.sinapse-ai/infrastructure/scripts/validate-codex-delegation.js +1 -4
- package/.sinapse-ai/infrastructure/scripts/validate-codex-integration.js +41 -5
- package/.sinapse-ai/infrastructure/templates/coderabbit.yaml.template +280 -280
- package/.sinapse-ai/infrastructure/templates/config/env.example +16 -16
- package/.sinapse-ai/infrastructure/templates/config/gitignore-additions.tmpl +59 -59
- package/.sinapse-ai/infrastructure/templates/github/CODEOWNERS.template +12 -12
- package/.sinapse-ai/infrastructure/templates/github-workflows/ci.yml.template +170 -170
- package/.sinapse-ai/infrastructure/templates/github-workflows/pr-automation.yml.template +331 -331
- package/.sinapse-ai/infrastructure/templates/github-workflows/release.yml.template +197 -197
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +19 -19
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-node.tmpl +86 -86
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-python.tmpl +146 -146
- package/.sinapse-ai/infrastructure/templates/gitignore/gitignore-sinapse-base.tmpl +64 -64
- package/.sinapse-ai/infrastructure/templates/safe-collab/CODEOWNERS.template +16 -16
- package/.sinapse-ai/infrastructure/templates/sinapse-sync.yaml.template +183 -183
- package/.sinapse-ai/install-manifest.yaml +112 -164
- package/.sinapse-ai/local-config.yaml.template +65 -65
- package/.sinapse-ai/product/templates/adr.hbs +126 -126
- package/.sinapse-ai/product/templates/dbdr.hbs +242 -242
- package/.sinapse-ai/product/templates/epic.hbs +213 -213
- package/.sinapse-ai/product/templates/ide-rules/codex-rules.md +30 -0
- package/.sinapse-ai/product/templates/pmdr.hbs +187 -187
- package/.sinapse-ai/product/templates/prd-v2.0.hbs +217 -217
- package/.sinapse-ai/product/templates/prd.hbs +202 -202
- package/.sinapse-ai/product/templates/statusline/statusline-script.js +31 -8
- package/.sinapse-ai/product/templates/statusline/track-agent-clear.cjs +79 -0
- package/.sinapse-ai/product/templates/statusline/track-agent.cjs +218 -0
- package/.sinapse-ai/product/templates/story.hbs +264 -264
- package/.sinapse-ai/product/templates/task.hbs +171 -171
- package/.sinapse-ai/product/templates/tmpl-comment-on-examples.sql +159 -159
- package/.sinapse-ai/product/templates/tmpl-migration-script.sql +92 -92
- package/.sinapse-ai/product/templates/tmpl-rls-granular-policies.sql +105 -105
- package/.sinapse-ai/product/templates/tmpl-rls-kiss-policy.sql +11 -11
- package/.sinapse-ai/product/templates/tmpl-rls-roles.sql +136 -136
- package/.sinapse-ai/product/templates/tmpl-rls-simple.sql +78 -78
- package/.sinapse-ai/product/templates/tmpl-rls-tenant.sql +153 -153
- package/.sinapse-ai/product/templates/tmpl-rollback-script.sql +78 -78
- package/.sinapse-ai/product/templates/tmpl-seed-data.sql +141 -141
- package/.sinapse-ai/product/templates/tmpl-smoke-test.sql +17 -17
- package/.sinapse-ai/product/templates/tmpl-staging-copy-merge.sql +140 -140
- package/.sinapse-ai/product/templates/tmpl-stored-proc.sql +141 -141
- package/.sinapse-ai/product/templates/tmpl-trigger.sql +153 -153
- package/.sinapse-ai/product/templates/tmpl-view-materialized.sql +134 -134
- package/.sinapse-ai/product/templates/tmpl-view.sql +178 -178
- package/AGENTS.md +193 -0
- package/CHANGELOG.md +1247 -0
- package/LICENSE +63 -63
- package/README.en.md +17 -18
- package/README.md +18 -19
- package/bin/cli.js +1 -1
- package/bin/commands/install.js +194 -22
- package/bin/commands/status.js +14 -1
- package/bin/commands/uninstall.js +2 -2
- package/bin/commands/update.js +52 -0
- package/bin/lib/setup-statusline.js +191 -0
- package/bin/sinapse-init.js +11 -83
- package/bin/utils/framework-guard.js +17 -4
- package/bin/utils/secret-scanner-core.js +109 -7
- package/bin/utils/staged-sql-guard.js +204 -0
- package/bin/utils/validate-publish.js +63 -0
- package/docs/agent-reference-guide.md +5 -7
- package/docs/framework/agent-prefix-convention.md +58 -0
- package/docs/framework/architecture-overview.md +4 -4
- package/docs/framework/collaboration-activation.md +45 -0
- package/docs/framework/guiding-principles.md +9 -9
- package/docs/getting-started.md +1 -1
- package/docs/guides/agent-reference.md +1 -1
- package/docs/guides/codex-config.md +4 -5
- package/docs/pt/architecture/sub-orqx-pattern.md +20 -18
- package/docs/security/overview.md +1 -1
- package/package.json +16 -12
- package/packages/installer/src/index.js +26 -0
- package/packages/installer/src/installer/git-hooks-installer.js +211 -47
- package/packages/installer/src/installer/sinapse-ai-installer.js +71 -0
- package/packages/installer/src/wizard/feedback.js +1 -1
- package/packages/installer/src/wizard/ide-config-generator.js +26 -26
- package/packages/installer/src/wizard/index.js +53 -4
- package/packages/sinapse-install/bin/edmcp.js +0 -0
- package/packages/sinapse-install/bin/sinapse-install.js +0 -0
- package/scripts/audit-tasks.cjs +112 -91
- package/scripts/check-markdown-links.py +352 -352
- package/scripts/prepare-hooks.js +58 -0
- package/scripts/regenerate-orqx-stubs.ps1 +2 -3
- package/scripts/sync-counts.js +10 -2
- package/scripts/sync-squad-yaml-components.js +108 -6
- package/scripts/validate-agents-md.js +128 -0
- package/scripts/validate-all.js +1 -0
- package/scripts/validate-squad-orqx.js +19 -9
- package/sinapse/agents/sinapse-orqx.md +16 -26
- package/sinapse/agents/snps-orqx.md +15 -25
- package/sinapse/knowledge-base/routing-catalog.md +1 -1
- package/sinapse/tasks/diagnose-and-route.md +1 -1
- package/sinapse/tasks/squad-status-report.md +1 -1
- package/squads/claude-code-mastery/agents/claude-mastery-chief.md +1 -1
- package/squads/claude-code-mastery/agents/hooks-architect.md +60 -68
- package/squads/claude-code-mastery/knowledge-base/swarm-orchestration-patterns.md +1 -1
- package/squads/claude-code-mastery/squad.yaml +8 -0
- package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
- package/squads/claude-code-mastery/workflows/optimization-cycle.yaml +4 -4
- package/squads/claude-code-mastery/workflows/project-setup-cycle.yaml +4 -4
- package/squads/squad-animations/README.md +1 -1
- package/squads/squad-animations/squad.yaml +1 -1
- package/squads/squad-brand/squad.yaml +1 -1
- package/squads/squad-cloning/README.md +1 -1
- package/squads/squad-cloning/squad.yaml +1 -1
- package/squads/squad-commercial/README.md +1 -1
- package/squads/squad-commercial/squad.yaml +2 -3
- package/squads/squad-content/README.md +1 -1
- package/squads/squad-content/squad.yaml +1 -1
- package/squads/squad-copy/README.md +1 -1
- package/squads/squad-copy/squad.yaml +2 -3
- package/squads/squad-council/README.md +1 -1
- package/squads/squad-courses/README.md +1 -1
- package/squads/squad-courses/squad.yaml +1 -1
- package/squads/squad-cybersecurity/README.md +1 -1
- package/squads/squad-cybersecurity/squad.yaml +2 -3
- package/squads/squad-design/README.md +1 -1
- package/squads/{squad-artdir → squad-design}/agents/cro-persuasion.md +1 -1
- package/squads/{squad-artdir → squad-design}/agents/platform-aesthetic-director.md +2 -2
- package/squads/{squad-artdir → squad-design}/agents/premium-packaging-strategist.md +2 -2
- package/squads/{squad-artdir → squad-design}/agents/product-surface-director.md +3 -3
- package/squads/squad-design/squad.yaml +6 -3
- package/squads/squad-finance/README.md +1 -1
- package/squads/squad-finance/squad.yaml +7 -1
- package/squads/squad-growth/README.md +1 -1
- package/squads/squad-growth/squad.yaml +1 -1
- package/squads/squad-paidmedia/README.md +1 -1
- package/squads/squad-paidmedia/squad.yaml +2 -3
- package/squads/squad-product/README.md +1 -1
- package/squads/squad-product/squad.yaml +1 -1
- package/squads/squad-research/README.md +1 -1
- package/squads/squad-research/squad.yaml +2 -3
- package/squads/squad-storytelling/README.md +1 -1
- package/squads/squad-storytelling/squad.yaml +2 -3
- package/.codex/agents/brad-frost.md +0 -46
- package/.codex/agents/claude-orqx.md +0 -72
- package/.codex/agents/copy-chief.md +0 -162
- package/.codex/agents/cyber-chief.md +0 -169
- package/.codex/agents/dan-mall.md +0 -43
- package/.codex/agents/data-chief.md +0 -198
- package/.codex/agents/dave-malouf.md +0 -43
- package/.codex/agents/db-sage.md +0 -152
- package/.codex/agents/design-chief.md +0 -226
- package/.codex/agents/dev.md +0 -102
- package/.codex/agents/legal-chief.md +0 -199
- package/.codex/agents/nano-banana-generator.md +0 -42
- package/.codex/agents/pm.md +0 -81
- package/.codex/agents/po.md +0 -85
- package/.codex/agents/qa.md +0 -98
- package/.codex/agents/sm.md +0 -77
- package/.codex/agents/squad-chief.md +0 -1553
- package/.codex/agents/squad.md +0 -66
- package/.codex/agents/story-chief.md +0 -180
- package/.codex/agents/tools-orqx.md +0 -219
- package/.codex/agents/traffic-masters-chief.md +0 -211
- package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +0 -265
- package/.sinapse-ai/core/permissions/__tests__/permission-mode.test.js +0 -293
- package/.sinapse-ai/data/registry-update-log.jsonl +0 -158
- package/.sinapse-ai/infrastructure/scripts/ide-sync/gemini-commands.js +0 -298
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/antigravity.js +0 -121
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/cursor.js +0 -119
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/github-copilot.js +0 -191
- package/.sinapse-ai/infrastructure/scripts/ide-sync/transformers/kimi.js +0 -448
- package/.sinapse-ai/infrastructure/tests/project-status-loader.test.js +0 -569
- package/.sinapse-ai/infrastructure/tests/regression-suite-v2.md +0 -622
- package/.sinapse-ai/infrastructure/tests/validate-module.js +0 -98
- package/.sinapse-ai/infrastructure/tests/worktree-manager.test.js +0 -620
- package/.sinapse-ai/monitor/hooks/lib/__init__.py +0 -2
- package/.sinapse-ai/monitor/hooks/lib/enrich.py +0 -59
- package/.sinapse-ai/monitor/hooks/lib/send_event.py +0 -48
- package/.sinapse-ai/monitor/hooks/notification.py +0 -30
- package/.sinapse-ai/monitor/hooks/post_tool_use.py +0 -46
- package/.sinapse-ai/monitor/hooks/pre_compact.py +0 -30
- package/.sinapse-ai/monitor/hooks/pre_tool_use.py +0 -41
- package/.sinapse-ai/monitor/hooks/stop.py +0 -30
- package/.sinapse-ai/monitor/hooks/subagent_stop.py +0 -30
- package/.sinapse-ai/monitor/hooks/user_prompt_submit.py +0 -39
- package/.sinapse-ai/product/templates/statusline/track-agent.sh +0 -69
- package/.sinapse-ai/workflow-intelligence/__tests__/confidence-scorer.test.js +0 -335
- package/.sinapse-ai/workflow-intelligence/__tests__/integration.test.js +0 -340
- package/.sinapse-ai/workflow-intelligence/__tests__/suggestion-engine.test.js +0 -438
- package/.sinapse-ai/workflow-intelligence/__tests__/wave-analyzer.test.js +0 -448
- package/.sinapse-ai/workflow-intelligence/__tests__/workflow-registry.test.js +0 -303
- package/bin/sinapse-graph.js +0 -19
- package/docs/codex-integration-process.md +0 -22
- package/docs/codex-parity-program.md +0 -27
- package/packages/installer/src/__tests__/performance-benchmark.js +0 -383
- package/packages/installer/tests/integration/environment-configuration.test.js +0 -332
- package/packages/installer/tests/integration/wizard-detection.test.js +0 -352
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +0 -383
- package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +0 -193
- package/packages/installer/tests/unit/config-validator.test.js +0 -315
- package/packages/installer/tests/unit/detection/detect-project-type.test.js +0 -539
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +0 -636
- package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +0 -192
- package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +0 -186
- package/packages/installer/tests/unit/env-template.test.js +0 -187
- package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +0 -310
- package/packages/installer/tests/unit/git-hooks-installer.test.js +0 -262
- package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +0 -231
- package/packages/installer/tests/unit/merger/env-merger.test.js +0 -191
- package/packages/installer/tests/unit/merger/markdown-merger.test.js +0 -262
- package/packages/installer/tests/unit/merger/strategies.test.js +0 -154
- package/packages/installer/tests/unit/merger/yaml-merger.test.js +0 -328
- package/packages/sinapse-install/tests/unit/chrome-brain.smoke.test.js +0 -66
- package/scripts/install-monitor-hooks.sh +0 -82
- package/squads/squad-artdir/README.md +0 -90
- package/squads/squad-artdir/agents/accessibility-guardian.md +0 -184
- package/squads/squad-artdir/agents/artdir-orqx.md +0 -222
- package/squads/squad-artdir/agents/color-psychologist.md +0 -166
- package/squads/squad-artdir/agents/design-system-architect.md +0 -100
- package/squads/squad-artdir/agents/ia-architect.md +0 -169
- package/squads/squad-artdir/agents/interaction-designer.md +0 -162
- package/squads/squad-artdir/agents/layout-engineer.md +0 -163
- package/squads/squad-artdir/agents/motion-architect.md +0 -185
- package/squads/squad-artdir/agents/type-systemist.md +0 -138
- package/squads/squad-artdir/agents/visual-strategist.md +0 -127
- package/squads/squad-artdir/checklists/seven-pillars-validation-checklist.md +0 -172
- package/squads/squad-artdir/knowledge-base/case-nyo-ia-reference.md +0 -289
- package/squads/squad-artdir/knowledge-base/deliverables-templates.md +0 -457
- package/squads/squad-artdir/knowledge-base/motion-technique-catalog.md +0 -247
- package/squads/squad-artdir/knowledge-base/premium-packaging-principles.md +0 -133
- package/squads/squad-artdir/knowledge-base/psychological-toolkit.md +0 -229
- package/squads/squad-artdir/knowledge-base/saas-art-direction-canon.md +0 -242
- package/squads/squad-artdir/knowledge-base/seven-pillars-framework.md +0 -289
- package/squads/squad-artdir/knowledge-base/ten-pillars-framework.md +0 -221
- package/squads/squad-artdir/package.json +0 -20
- package/squads/squad-artdir/squad.yaml +0 -299
- package/squads/squad-artdir/tasks/audit-conversion.md +0 -97
- package/squads/squad-artdir/tasks/audit-drift-multi-surface.md +0 -55
- package/squads/squad-artdir/tasks/consult-saas-canon.md +0 -54
- package/squads/squad-artdir/tasks/create-art-direction-brief.md +0 -110
- package/squads/squad-artdir/tasks/create-premium-packaging-brief.md +0 -61
- package/squads/squad-artdir/tasks/create-wireflow.md +0 -84
- package/squads/squad-artdir/tasks/design-color-system.md +0 -81
- package/squads/squad-artdir/tasks/design-product-surface.md +0 -60
- package/squads/squad-artdir/tasks/design-token-system.md +0 -58
- package/squads/squad-artdir/tasks/diagnose-visual-language.md +0 -92
- package/squads/squad-artdir/tasks/first-5-minutes-choreography.md +0 -65
- package/squads/squad-artdir/tasks/specify-motion-system.md +0 -84
- package/squads/squad-artdir/tasks/validate-against-pillars.md +0 -143
- package/squads/squad-artdir/templates/art-direction-brief-template.md +0 -215
- package/squads/squad-artdir/workflows/conversion-audit-cycle.yaml +0 -142
- package/squads/squad-artdir/workflows/full-art-direction-cycle.yaml +0 -179
- package/squads/squad-artdir/workflows/saas-platform-art-direction-cycle.yaml +0 -338
- package/squads/squad-commercial/agents/legal-chief.md +0 -199
- package/squads/squad-copy/agents/copy-chief.md +0 -162
- package/squads/squad-cybersecurity/agents/cyber-chief.md +0 -169
- package/squads/squad-design/agents/design-chief.md +0 -226
- package/squads/squad-paidmedia/agents/traffic-masters-chief.md +0 -211
- package/squads/squad-research/agents/data-chief.md +0 -198
- package/squads/squad-storytelling/agents/story-chief.md +0 -180
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Behavioral pointer/orphan resolver for the Codex catalog (anti-fachada).
|
|
6
|
+
*
|
|
7
|
+
* The legacy integration validator only COUNTED markdown files: a green check
|
|
8
|
+
* meant "file present", never "file resolves". This module OPENS each Codex
|
|
9
|
+
* agent pointer and RESOLVES it against the real source-of-truth set:
|
|
10
|
+
*
|
|
11
|
+
* - Core/dev agents: `.sinapse-ai/development/agents/{id}.md`
|
|
12
|
+
* - Squad agents: `squads/{squad}/agents/{id}.md`
|
|
13
|
+
*
|
|
14
|
+
* It detects two failure classes the count-based check is blind to:
|
|
15
|
+
*
|
|
16
|
+
* 1. BROKEN POINTER — a `.codex/agents/*.md` whose "Read the agent definition
|
|
17
|
+
* at: {path}" target does NOT exist on disk (the squad-claude →
|
|
18
|
+
* claude-code-mastery rename class), OR a core agent with no pointer line
|
|
19
|
+
* and no `{id}.md` in the dev agents dir.
|
|
20
|
+
*
|
|
21
|
+
* 2. ORPHAN — a `.codex/agents/*.md` whose stem has no corresponding source
|
|
22
|
+
* agent anywhere (retired chiefs, brad-frost/dan-mall, etc.). An orphan is
|
|
23
|
+
* a catalog entry that can never resolve to a real agent.
|
|
24
|
+
*
|
|
25
|
+
* It is intentionally dependency-light (fs only) so the validator never needs
|
|
26
|
+
* the heavier activator wiring to answer "is this catalog honest?".
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const fs = require('fs');
|
|
30
|
+
const path = require('path');
|
|
31
|
+
|
|
32
|
+
const POINTER_RE = /Read the agent definition at:\s*(\S+)/i;
|
|
33
|
+
|
|
34
|
+
function listMarkdown(dirAbs) {
|
|
35
|
+
try {
|
|
36
|
+
return fs.readdirSync(dirAbs).filter((f) => f.endsWith('.md'));
|
|
37
|
+
} catch {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function fileExists(absPath) {
|
|
43
|
+
try {
|
|
44
|
+
return fs.statSync(absPath).isFile();
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build the canonical source set: every agent that actually has a definition
|
|
52
|
+
* on disk, keyed by its file stem.
|
|
53
|
+
* stem -> { stem, sourcePath, squad|null }
|
|
54
|
+
*/
|
|
55
|
+
function buildSourceIndex(projectRoot, config = {}) {
|
|
56
|
+
const index = new Map();
|
|
57
|
+
|
|
58
|
+
const devAgentsRel = config.canonicalAgentsDir || '.sinapse-ai/development/agents';
|
|
59
|
+
for (const file of listMarkdown(path.join(projectRoot, devAgentsRel))) {
|
|
60
|
+
const stem = file.replace(/\.md$/, '');
|
|
61
|
+
index.set(stem, { stem, sourcePath: `${devAgentsRel}/${file}`, squad: null });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const squadsRel = config.squadsDir || 'squads';
|
|
65
|
+
const squadsAbs = path.join(projectRoot, squadsRel);
|
|
66
|
+
let squadDirs = [];
|
|
67
|
+
try {
|
|
68
|
+
squadDirs = fs
|
|
69
|
+
.readdirSync(squadsAbs)
|
|
70
|
+
.filter((d) => {
|
|
71
|
+
try {
|
|
72
|
+
return fs.statSync(path.join(squadsAbs, d)).isDirectory();
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
} catch {
|
|
78
|
+
squadDirs = [];
|
|
79
|
+
}
|
|
80
|
+
for (const squad of squadDirs) {
|
|
81
|
+
const agentsRel = `${squadsRel}/${squad}/agents`;
|
|
82
|
+
for (const file of listMarkdown(path.join(projectRoot, agentsRel))) {
|
|
83
|
+
const stem = file.replace(/\.md$/, '');
|
|
84
|
+
// First squad wins; a later duplicate stem is still a real source.
|
|
85
|
+
if (!index.has(stem)) {
|
|
86
|
+
index.set(stem, { stem, sourcePath: `${agentsRel}/${file}`, squad });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return index;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Resolve every Codex agent pointer against the source index.
|
|
96
|
+
* Returns { brokenPointers[], orphans[], resolved[], total }.
|
|
97
|
+
*/
|
|
98
|
+
function resolveCatalog(projectRoot = process.cwd(), config = {}) {
|
|
99
|
+
const codexAgentsRel = config.codexAgentsDir || '.codex/agents';
|
|
100
|
+
const codexAgentsAbs = path.join(projectRoot, codexAgentsRel);
|
|
101
|
+
const devAgentsRel = config.canonicalAgentsDir || '.sinapse-ai/development/agents';
|
|
102
|
+
|
|
103
|
+
const sourceIndex = buildSourceIndex(projectRoot, config);
|
|
104
|
+
|
|
105
|
+
const brokenPointers = [];
|
|
106
|
+
const orphans = [];
|
|
107
|
+
const resolved = [];
|
|
108
|
+
|
|
109
|
+
const codexFiles = listMarkdown(codexAgentsAbs);
|
|
110
|
+
|
|
111
|
+
for (const file of codexFiles) {
|
|
112
|
+
const stem = file.replace(/\.md$/, '');
|
|
113
|
+
const pointerRel = `${codexAgentsRel}/${file}`;
|
|
114
|
+
let raw = '';
|
|
115
|
+
try {
|
|
116
|
+
raw = fs.readFileSync(path.join(codexAgentsAbs, file), 'utf8');
|
|
117
|
+
} catch {
|
|
118
|
+
raw = '';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const m = raw.match(POINTER_RE);
|
|
122
|
+
let target = m ? m[1].trim().replace(/\r$/, '') : null;
|
|
123
|
+
|
|
124
|
+
// Core/dev agents may omit the pointer line and resolve by id convention.
|
|
125
|
+
if (!target && fileExists(path.join(projectRoot, `${devAgentsRel}/${stem}.md`))) {
|
|
126
|
+
target = `${devAgentsRel}/${stem}.md`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ORPHAN: stem has no source agent anywhere in the ecosystem.
|
|
130
|
+
if (!sourceIndex.has(stem)) {
|
|
131
|
+
orphans.push({ id: stem, pointer: pointerRel, target });
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// BROKEN: no pointer target at all, or the declared target file is missing.
|
|
136
|
+
if (!target) {
|
|
137
|
+
brokenPointers.push({ id: stem, pointer: pointerRel, target: null, reason: 'no pointer line' });
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (!fileExists(path.join(projectRoot, target))) {
|
|
141
|
+
brokenPointers.push({ id: stem, pointer: pointerRel, target, reason: 'target missing' });
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
resolved.push({ id: stem, pointer: pointerRel, target });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
brokenPointers,
|
|
150
|
+
orphans,
|
|
151
|
+
resolved,
|
|
152
|
+
total: codexFiles.length,
|
|
153
|
+
sourceCount: sourceIndex.size,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
module.exports = {
|
|
158
|
+
buildSourceIndex,
|
|
159
|
+
resolveCatalog,
|
|
160
|
+
POINTER_RE,
|
|
161
|
+
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dashboard Status Writer
|
|
3
3
|
*
|
|
4
|
-
* Writes the current SINAPSE agent status to .sinapse/dashboard/status.json
|
|
5
|
-
*
|
|
4
|
+
* Writes the current SINAPSE agent status to .sinapse/dashboard/status.json.
|
|
5
|
+
*
|
|
6
|
+
* Note: this file is a plain on-disk status snapshot. The CLI observability
|
|
7
|
+
* panel (`sinapse status --watch`) tails it. The old web dashboard that
|
|
8
|
+
* consumed it over SSE was the localhost:4001 monitor, which was ARCHIVED
|
|
9
|
+
* (16/06/2026, Etapa 7 / D6) — there is no SSE stream anymore, just the file.
|
|
6
10
|
*
|
|
7
11
|
* Usage:
|
|
8
12
|
* const statusWriter = require('./dashboard-status-writer');
|
|
@@ -21,17 +21,12 @@ const fs = require('fs-extra');
|
|
|
21
21
|
const path = require('path');
|
|
22
22
|
const yaml = require('js-yaml');
|
|
23
23
|
|
|
24
|
-
const { parseAllAgents } = require('./agent-parser');
|
|
24
|
+
const { parseAllAgents, parseAgentFile } = require('./agent-parser');
|
|
25
25
|
const { generateAllRedirects, writeRedirects } = require('./redirect-generator');
|
|
26
26
|
const { validateAllIdes, formatValidationReport } = require('./validator');
|
|
27
|
-
const { syncGeminiCommands, buildGeminiCommandFiles } = require('./gemini-commands');
|
|
28
27
|
|
|
29
|
-
// Transformers
|
|
28
|
+
// Transformers (Claude Code + Codex only — secondary IDE adapters removed)
|
|
30
29
|
const claudeCodeTransformer = require('./transformers/claude-code');
|
|
31
|
-
const cursorTransformer = require('./transformers/cursor');
|
|
32
|
-
const antigravityTransformer = require('./transformers/antigravity');
|
|
33
|
-
const githubCopilotTransformer = require('./transformers/github-copilot');
|
|
34
|
-
const kimiTransformer = require(path.resolve(__dirname, 'transformers', 'kimi'));
|
|
35
30
|
|
|
36
31
|
// ANSI colors for output
|
|
37
32
|
const colors = {
|
|
@@ -63,36 +58,16 @@ function loadConfig(projectRoot) {
|
|
|
63
58
|
path: '.claude/commands/SINAPSE/agents',
|
|
64
59
|
format: 'full-markdown-yaml',
|
|
65
60
|
},
|
|
61
|
+
// Post-E8: .codex is owned by the canonical Codex sync
|
|
62
|
+
// (sync-codex-local-first.js), which writes thin runtime pointers
|
|
63
|
+
// resolved at runtime by resolve-codex-agent.js. ide-sync drives
|
|
64
|
+
// claude-code only now; leaving this enabled would clobber those
|
|
65
|
+
// pointers with full agent bodies on a bare `sync:ide`.
|
|
66
66
|
codex: {
|
|
67
|
-
enabled:
|
|
67
|
+
enabled: false,
|
|
68
68
|
path: '.codex/agents',
|
|
69
69
|
format: 'full-markdown-yaml',
|
|
70
70
|
},
|
|
71
|
-
gemini: {
|
|
72
|
-
enabled: true,
|
|
73
|
-
path: '.gemini/rules/SINAPSE/agents',
|
|
74
|
-
format: 'full-markdown-yaml',
|
|
75
|
-
},
|
|
76
|
-
'github-copilot': {
|
|
77
|
-
enabled: true,
|
|
78
|
-
path: '.github/agents',
|
|
79
|
-
format: 'github-copilot',
|
|
80
|
-
},
|
|
81
|
-
cursor: {
|
|
82
|
-
enabled: true,
|
|
83
|
-
path: '.cursor/rules/agents',
|
|
84
|
-
format: 'condensed-rules',
|
|
85
|
-
},
|
|
86
|
-
antigravity: {
|
|
87
|
-
enabled: true,
|
|
88
|
-
path: '.antigravity/rules/agents',
|
|
89
|
-
format: 'cursor-style',
|
|
90
|
-
},
|
|
91
|
-
kimi: {
|
|
92
|
-
enabled: true,
|
|
93
|
-
path: '.kimi/skills',
|
|
94
|
-
format: 'kimi-skill',
|
|
95
|
-
},
|
|
96
71
|
},
|
|
97
72
|
redirects: {
|
|
98
73
|
'sinapse-developer': 'sinapse-orqx',
|
|
@@ -131,10 +106,6 @@ function loadConfig(projectRoot) {
|
|
|
131
106
|
function getTransformer(format) {
|
|
132
107
|
const transformers = {
|
|
133
108
|
'full-markdown-yaml': claudeCodeTransformer,
|
|
134
|
-
'condensed-rules': cursorTransformer,
|
|
135
|
-
'cursor-style': antigravityTransformer,
|
|
136
|
-
'github-copilot': githubCopilotTransformer,
|
|
137
|
-
'kimi-skill': kimiTransformer,
|
|
138
109
|
};
|
|
139
110
|
|
|
140
111
|
const transformer = transformers[format];
|
|
@@ -212,15 +183,13 @@ function syncIde(agents, ideConfig, ideName, projectRoot, options) {
|
|
|
212
183
|
|
|
213
184
|
// Transform and write each agent
|
|
214
185
|
for (const agent of agents) {
|
|
215
|
-
// Skip
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
if (agent.error && agent.error === 'No YAML block found') {
|
|
186
|
+
// Skip only when there is no content at all to mirror. The claude-code
|
|
187
|
+
// transform is an identity copy of the raw file body, so an agent whose
|
|
188
|
+
// YAML block is missing/malformed but whose body exists can still be
|
|
189
|
+
// synced verbatim — e.g. the prose-format squad orqx
|
|
190
|
+
// (commercial/finance/paidmedia) pending standardization to the canonical
|
|
191
|
+
// fenced yaml block (E6). Genuinely empty/unreadable files are skipped.
|
|
192
|
+
if (agent.error && !agent.raw) {
|
|
224
193
|
result.errors.push({
|
|
225
194
|
agent: agent.id,
|
|
226
195
|
error: agent.error,
|
|
@@ -275,6 +244,52 @@ function syncIde(agents, ideConfig, ideName, projectRoot, options) {
|
|
|
275
244
|
return result;
|
|
276
245
|
}
|
|
277
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Collect squad orchestrator agents (squads/SQUAD/agents/*-orqx.md).
|
|
249
|
+
*
|
|
250
|
+
* Framework-core agents come from config.source
|
|
251
|
+
* (.sinapse-ai/development/agents). The 17 squad orchestrators live under
|
|
252
|
+
* squads/** and were never enumerated here — so the Claude IDE dir only ever
|
|
253
|
+
* received the 12 core agents, and the doctor ide-sync check (which expects
|
|
254
|
+
* core + orqx) rightly WARNed. This mirrors the discovery logic in
|
|
255
|
+
* core/doctor/checks/ide-sync.js so the two always agree. Filenames are the
|
|
256
|
+
* flat basename (e.g. brand-orqx.md), via the claude-code transformer's
|
|
257
|
+
* getFilename, even though the YAML id is "squad-brand/brand-orqx".
|
|
258
|
+
*
|
|
259
|
+
* @param {string} projectRoot - Project root directory
|
|
260
|
+
* @returns {object[]} - Parsed orqx agent data
|
|
261
|
+
*/
|
|
262
|
+
function collectSquadOrqxAgents(projectRoot) {
|
|
263
|
+
const squadsRoot = path.join(projectRoot, 'squads');
|
|
264
|
+
const out = [];
|
|
265
|
+
if (!fs.existsSync(squadsRoot)) return out;
|
|
266
|
+
|
|
267
|
+
let squadDirs = [];
|
|
268
|
+
try {
|
|
269
|
+
squadDirs = fs
|
|
270
|
+
.readdirSync(squadsRoot, { withFileTypes: true })
|
|
271
|
+
.filter((e) => e.isDirectory())
|
|
272
|
+
.map((e) => e.name);
|
|
273
|
+
} catch {
|
|
274
|
+
return out;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
for (const squadName of squadDirs) {
|
|
278
|
+
const agentsDir = path.join(squadsRoot, squadName, 'agents');
|
|
279
|
+
if (!fs.existsSync(agentsDir)) continue;
|
|
280
|
+
let files = [];
|
|
281
|
+
try {
|
|
282
|
+
files = fs.readdirSync(agentsDir).filter((f) => f.endsWith('-orqx.md'));
|
|
283
|
+
} catch {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
for (const file of files) {
|
|
287
|
+
out.push(parseAgentFile(path.join(agentsDir, file)));
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return out;
|
|
291
|
+
}
|
|
292
|
+
|
|
278
293
|
/**
|
|
279
294
|
* Execute sync command
|
|
280
295
|
* @param {object} options - Command options
|
|
@@ -301,7 +316,7 @@ async function commandSync(options) {
|
|
|
301
316
|
console.log(`${colors.dim}Source: ${agentsDir}${colors.reset}`);
|
|
302
317
|
}
|
|
303
318
|
|
|
304
|
-
const agents = parseAllAgents(agentsDir);
|
|
319
|
+
const agents = [...parseAllAgents(agentsDir), ...collectSquadOrqxAgents(projectRoot)];
|
|
305
320
|
if (!options.quiet) {
|
|
306
321
|
console.log(`${colors.dim}Found ${agents.length} agents${colors.reset}`);
|
|
307
322
|
console.log('');
|
|
@@ -334,13 +349,7 @@ async function commandSync(options) {
|
|
|
334
349
|
|
|
335
350
|
const result = syncIde(agents, ideConfig, ideName, projectRoot, options);
|
|
336
351
|
|
|
337
|
-
|
|
338
|
-
if (ideName === 'gemini') {
|
|
339
|
-
const geminiCommands = syncGeminiCommands(agents, projectRoot, options);
|
|
340
|
-
result.commandFiles = geminiCommands.files;
|
|
341
|
-
} else {
|
|
342
|
-
result.commandFiles = [];
|
|
343
|
-
}
|
|
352
|
+
result.commandFiles = [];
|
|
344
353
|
|
|
345
354
|
results.push(result);
|
|
346
355
|
|
|
@@ -416,9 +425,9 @@ async function commandValidate(options) {
|
|
|
416
425
|
console.log(`${colors.bright}${colors.blue}🔍 IDE Sync Validation${colors.reset}`);
|
|
417
426
|
console.log('');
|
|
418
427
|
|
|
419
|
-
// Parse all agents
|
|
428
|
+
// Parse all agents (framework core + squad orchestrators)
|
|
420
429
|
const agentsDir = path.join(projectRoot, config.source);
|
|
421
|
-
const agents = parseAllAgents(agentsDir);
|
|
430
|
+
const agents = [...parseAllAgents(agentsDir), ...collectSquadOrqxAgents(projectRoot)];
|
|
422
431
|
|
|
423
432
|
// Build expected files for each IDE
|
|
424
433
|
const ideConfigs = {};
|
|
@@ -473,18 +482,6 @@ async function commandValidate(options) {
|
|
|
473
482
|
expectedFiles,
|
|
474
483
|
targetDir: path.join(projectRoot, ideConfig.path),
|
|
475
484
|
};
|
|
476
|
-
|
|
477
|
-
// Gemini CLI command launcher files are synced under .gemini/commands/*.toml
|
|
478
|
-
if (ideName === 'gemini') {
|
|
479
|
-
const commandFiles = buildGeminiCommandFiles(agents).map((entry) => ({
|
|
480
|
-
filename: entry.filename,
|
|
481
|
-
content: entry.content,
|
|
482
|
-
}));
|
|
483
|
-
ideConfigs['gemini-commands'] = {
|
|
484
|
-
expectedFiles: commandFiles,
|
|
485
|
-
targetDir: path.join(projectRoot, '.gemini', 'commands'),
|
|
486
|
-
};
|
|
487
|
-
}
|
|
488
485
|
}
|
|
489
486
|
|
|
490
487
|
// Validate
|
|
@@ -21,6 +21,135 @@ function countMarkdownFiles(dirPath) {
|
|
|
21
21
|
return fs.readdirSync(dirPath).filter((entry) => entry.endsWith('.md')).length;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Build the canonical agent source map.
|
|
26
|
+
* Source of truth = framework core agents (canonicalAgentsDir, flat *.md)
|
|
27
|
+
* + every squad specialist/orchestrator under squads/<squad>/agents/*.md.
|
|
28
|
+
*
|
|
29
|
+
* The result keys agents by id (filename without .md). When the same id exists
|
|
30
|
+
* in more than one place, core wins, then the first squad alphabetically — but in
|
|
31
|
+
* practice ids are unique across the ecosystem. Deprecated folders (e.g.
|
|
32
|
+
* squads/<squad>/_deprecated) are intentionally NOT scanned, so retired agents
|
|
33
|
+
* never re-enter the catalog.
|
|
34
|
+
*
|
|
35
|
+
* @param {string} projectRoot
|
|
36
|
+
* @param {string} canonicalAgentsDir - relative path to core agents dir
|
|
37
|
+
* @param {string} squadsDir - relative path to squads root (default 'squads')
|
|
38
|
+
* @returns {Map<string, {id: string, squad: string, sourcePath: string}>}
|
|
39
|
+
*/
|
|
40
|
+
function buildAgentSourceMap(projectRoot, canonicalAgentsDir, squadsDir = 'squads') {
|
|
41
|
+
const map = new Map();
|
|
42
|
+
|
|
43
|
+
const addAgent = (filePath, squad) => {
|
|
44
|
+
if (!filePath.endsWith('.md')) return;
|
|
45
|
+
const id = path.basename(filePath, '.md');
|
|
46
|
+
if (map.has(id)) return; // first writer wins (core scanned first)
|
|
47
|
+
map.set(id, {
|
|
48
|
+
id,
|
|
49
|
+
squad,
|
|
50
|
+
sourcePath: path.relative(projectRoot, filePath).split(path.sep).join('/'),
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// 1. Framework core agents (flat *.md only — ignore persona subfolders)
|
|
55
|
+
const coreDir = path.join(projectRoot, canonicalAgentsDir);
|
|
56
|
+
if (fs.existsSync(coreDir)) {
|
|
57
|
+
for (const entry of fs.readdirSync(coreDir, { withFileTypes: true })) {
|
|
58
|
+
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
59
|
+
addAgent(path.join(coreDir, entry.name), 'core');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 2. Squad specialists + orchestrators
|
|
65
|
+
const squadsRoot = path.join(projectRoot, squadsDir);
|
|
66
|
+
if (fs.existsSync(squadsRoot)) {
|
|
67
|
+
for (const squadEntry of fs.readdirSync(squadsRoot, { withFileTypes: true })) {
|
|
68
|
+
if (!squadEntry.isDirectory()) continue;
|
|
69
|
+
const squadName = squadEntry.name;
|
|
70
|
+
const agentsDir = path.join(squadsRoot, squadName, 'agents');
|
|
71
|
+
if (!fs.existsSync(agentsDir)) continue;
|
|
72
|
+
for (const agentEntry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
|
|
73
|
+
// Only top-level *.md — skip _deprecated/ and persona subfolders
|
|
74
|
+
if (agentEntry.isFile() && agentEntry.name.endsWith('.md')) {
|
|
75
|
+
addAgent(path.join(agentsDir, agentEntry.name), squadName);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return map;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Render the Codex activator pointer for an agent. Thin by design (D7):
|
|
86
|
+
* Codex reads the real persona/tasks from the canonical source, so the pointer
|
|
87
|
+
* never copies content — it only routes to the source of truth.
|
|
88
|
+
*
|
|
89
|
+
* @param {{id: string, squad: string, sourcePath: string}} agent
|
|
90
|
+
* @returns {string}
|
|
91
|
+
*/
|
|
92
|
+
function renderCodexActivator(agent) {
|
|
93
|
+
return [
|
|
94
|
+
`Activate agent: ${agent.id}`,
|
|
95
|
+
`Squad: ${agent.squad}`,
|
|
96
|
+
`Read the agent definition at: ${agent.sourcePath}`,
|
|
97
|
+
'Follow ALL instructions in the agent file. Adopt the persona, use the frameworks, and respond as that agent.',
|
|
98
|
+
'',
|
|
99
|
+
].join('\n');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Regenerate .codex/agents from the canonical source map, idempotently.
|
|
104
|
+
* - Writes/updates one activator per source agent (pointers always valid,
|
|
105
|
+
* because the target path is derived from where the file actually lives).
|
|
106
|
+
* - Prunes any .codex agent whose id is not in the source set (removes orphans
|
|
107
|
+
* such as retired chiefs and squad-artdir personas).
|
|
108
|
+
*
|
|
109
|
+
* @returns {{written: string[], pruned: string[], total: number}}
|
|
110
|
+
*/
|
|
111
|
+
function regenerateCodexAgents(agentsDir, sourceMap, options = {}) {
|
|
112
|
+
const dryRun = Boolean(options.dryRun);
|
|
113
|
+
const written = [];
|
|
114
|
+
const pruned = [];
|
|
115
|
+
|
|
116
|
+
if (!dryRun) {
|
|
117
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 1. Write/refresh pointers for every canonical agent
|
|
121
|
+
for (const agent of sourceMap.values()) {
|
|
122
|
+
const target = path.join(agentsDir, `${agent.id}.md`);
|
|
123
|
+
const next = renderCodexActivator(agent);
|
|
124
|
+
let current = null;
|
|
125
|
+
if (fs.existsSync(target)) {
|
|
126
|
+
current = fs.readFileSync(target, 'utf8');
|
|
127
|
+
}
|
|
128
|
+
if (current !== next) {
|
|
129
|
+
if (!dryRun) fs.writeFileSync(target, next, 'utf8');
|
|
130
|
+
written.push(`${agent.id}.md`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 2. Prune orphans (present in .codex but absent from source)
|
|
135
|
+
if (fs.existsSync(agentsDir)) {
|
|
136
|
+
for (const entry of fs.readdirSync(agentsDir)) {
|
|
137
|
+
if (!entry.endsWith('.md')) continue;
|
|
138
|
+
const id = entry.slice(0, -'.md'.length);
|
|
139
|
+
if (!sourceMap.has(id)) {
|
|
140
|
+
if (!dryRun) fs.rmSync(path.join(agentsDir, entry), { force: true });
|
|
141
|
+
pruned.push(entry);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
written,
|
|
148
|
+
pruned,
|
|
149
|
+
total: sourceMap.size,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
24
153
|
function countSkillFiles(skillsDir) {
|
|
25
154
|
if (!fs.existsSync(skillsDir)) return 0;
|
|
26
155
|
return fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
@@ -88,6 +217,20 @@ function syncCodexLocalFirst(options = {}, deps = {}) {
|
|
|
88
217
|
};
|
|
89
218
|
}
|
|
90
219
|
|
|
220
|
+
// Regenerate the agent catalog from the canonical source of truth.
|
|
221
|
+
// This replaces the old "preserve whatever is on disk" behaviour that froze
|
|
222
|
+
// the snapshot and perpetuated broken pointers + retired orphans.
|
|
223
|
+
const sourceMap = (deps.buildAgentSourceMap || buildAgentSourceMap)(
|
|
224
|
+
projectRoot,
|
|
225
|
+
config.canonicalAgentsDir || '.sinapse-ai/development/agents',
|
|
226
|
+
config.squadsDir || 'squads',
|
|
227
|
+
);
|
|
228
|
+
const regen = (deps.regenerateCodexAgents || regenerateCodexAgents)(
|
|
229
|
+
agentsDir,
|
|
230
|
+
sourceMap,
|
|
231
|
+
{ dryRun: Boolean(options.dryRun) },
|
|
232
|
+
);
|
|
233
|
+
|
|
91
234
|
const syncResult = runSyncSkills({
|
|
92
235
|
projectRoot,
|
|
93
236
|
sourceDir,
|
|
@@ -104,6 +247,8 @@ function syncCodexLocalFirst(options = {}, deps = {}) {
|
|
|
104
247
|
errors: [],
|
|
105
248
|
metrics: {
|
|
106
249
|
codexAgents: countMarkdownFiles(agentsDir),
|
|
250
|
+
agentsRegenerated: regen.written.length,
|
|
251
|
+
agentsPruned: regen.pruned.length,
|
|
107
252
|
codexSkills: countSkillFiles(skillsDir),
|
|
108
253
|
generatedSkills: syncResult.generated,
|
|
109
254
|
},
|
|
@@ -122,7 +267,14 @@ function formatHumanReport(result) {
|
|
|
122
267
|
].join('\n');
|
|
123
268
|
}
|
|
124
269
|
|
|
125
|
-
return
|
|
270
|
+
return (
|
|
271
|
+
`OK Codex local-first sync complete ` +
|
|
272
|
+
`(agents: ${result.metrics.codexAgents}, ` +
|
|
273
|
+
`regenerated: ${result.metrics.agentsRegenerated ?? 0}, ` +
|
|
274
|
+
`pruned: ${result.metrics.agentsPruned ?? 0}, ` +
|
|
275
|
+
`total skills: ${result.metrics.codexSkills}, ` +
|
|
276
|
+
`skills regenerated: ${result.metrics.generatedSkills})`
|
|
277
|
+
);
|
|
126
278
|
}
|
|
127
279
|
|
|
128
280
|
function main() {
|
|
@@ -153,4 +305,7 @@ module.exports = {
|
|
|
153
305
|
runLegacyCodexSync,
|
|
154
306
|
countMarkdownFiles,
|
|
155
307
|
countSkillFiles,
|
|
308
|
+
buildAgentSourceMap,
|
|
309
|
+
renderCodexActivator,
|
|
310
|
+
regenerateCodexAgents,
|
|
156
311
|
};
|
|
@@ -6,10 +6,8 @@ const path = require('path');
|
|
|
6
6
|
const Ajv2020 = require('ajv/dist/2020');
|
|
7
7
|
const {
|
|
8
8
|
loadDelegationMatrix,
|
|
9
|
-
} = require(path.join(__dirname, '..', '..', '..', '.codex', 'scripts', 'resolve-codex-delegation'));
|
|
10
|
-
const {
|
|
11
9
|
buildHandoffPacket,
|
|
12
|
-
} = require(path.join(__dirname, '..', '..', '..', '.codex', 'scripts', 'resolve-codex-delegation
|
|
10
|
+
} = require(path.join(__dirname, '..', '..', '..', '.codex', 'scripts', 'resolve-codex-delegation'));
|
|
13
11
|
const {
|
|
14
12
|
loadRegistry: loadCommandRegistryFile,
|
|
15
13
|
} = require('./validate-codex-command-registry');
|
|
@@ -27,7 +25,6 @@ const REQUIRED_ORCHESTRATORS = Object.freeze([
|
|
|
27
25
|
'paidmedia-orqx',
|
|
28
26
|
'product-orqx',
|
|
29
27
|
'research-orqx',
|
|
30
|
-
'claude-orqx',
|
|
31
28
|
'council-orqx',
|
|
32
29
|
'storytelling-orqx',
|
|
33
30
|
'cyber-orqx',
|
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
loadCodexCatalogConfig,
|
|
8
8
|
getConfiguredSkillIds,
|
|
9
9
|
} = require('./codex-parity/catalog');
|
|
10
|
+
const { resolveCatalog } = require('./codex-parity/resolve');
|
|
10
11
|
|
|
11
12
|
function getDefaultOptions() {
|
|
12
13
|
const projectRoot = process.cwd();
|
|
@@ -77,14 +78,45 @@ function validateCodexIntegration(options = {}) {
|
|
|
77
78
|
const codexSkillsCount = countSkillFiles(resolved.skillsDir);
|
|
78
79
|
const expectedSkillIds = getConfiguredSkillIds(config);
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
// --- Behavioral resolution (anti-fachada) --------------------------------
|
|
82
|
+
// Open every Codex agent pointer and RESOLVE it against the real
|
|
83
|
+
// source-of-truth set. A present file is not parity; a resolving pointer is.
|
|
84
|
+
const catalog = resolveCatalog(resolved.projectRoot, {
|
|
85
|
+
canonicalAgentsDir: config.canonicalAgentsDir || '.sinapse-ai/development/agents',
|
|
86
|
+
codexAgentsDir: config.codexAgentsDir || '.codex/agents',
|
|
87
|
+
squadsDir: config.squadsDir || 'squads',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
for (const broken of catalog.brokenPointers) {
|
|
91
|
+
errors.push(
|
|
92
|
+
`Broken Codex pointer: ${broken.id} -> ${broken.target || '(no target)'} (${broken.reason})`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const orphan of catalog.orphans) {
|
|
97
|
+
errors.push(
|
|
98
|
+
`Orphan Codex agent: ${orphan.id} has no source-of-truth in the canonical agent set`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// --- Count parity: MISMATCH is now an ERROR, not a soft warning ----------
|
|
103
|
+
// In expanded mode the Codex catalog is the full ecosystem (172), which is
|
|
104
|
+
// intentionally larger than the dev/core agents dir. Parity is measured
|
|
105
|
+
// against the resolvable source set, not the dev dir.
|
|
106
|
+
if (config.catalogMode === 'expanded') {
|
|
107
|
+
if (codexAgentsCount !== catalog.resolved.length) {
|
|
108
|
+
errors.push(
|
|
109
|
+
`Codex agent count mismatch: ${codexAgentsCount} catalog file(s) but only ${catalog.resolved.length} resolve cleanly`,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
} else if (sourceCount > 0 && codexAgentsCount !== sourceCount) {
|
|
113
|
+
errors.push(`Codex agent count differs from source (${codexAgentsCount}/${sourceCount})`);
|
|
82
114
|
}
|
|
83
115
|
|
|
84
116
|
if (expectedSkillIds && codexSkillsCount !== expectedSkillIds.length) {
|
|
85
|
-
|
|
117
|
+
errors.push(`Codex skill count differs from configured catalog (${codexSkillsCount}/${expectedSkillIds.length})`);
|
|
86
118
|
} else if (!expectedSkillIds && sourceCount > 0 && codexSkillsCount !== sourceCount) {
|
|
87
|
-
|
|
119
|
+
errors.push(`Codex skill count differs from source (${codexSkillsCount}/${sourceCount})`);
|
|
88
120
|
}
|
|
89
121
|
|
|
90
122
|
return {
|
|
@@ -96,6 +128,10 @@ function validateCodexIntegration(options = {}) {
|
|
|
96
128
|
codexAgents: codexAgentsCount,
|
|
97
129
|
codexSkills: codexSkillsCount,
|
|
98
130
|
expectedSkills: expectedSkillIds ? expectedSkillIds.length : sourceCount,
|
|
131
|
+
resolvedPointers: catalog.resolved.length,
|
|
132
|
+
brokenPointers: catalog.brokenPointers.length,
|
|
133
|
+
orphans: catalog.orphans.length,
|
|
134
|
+
sourceAgents: catalog.sourceCount,
|
|
99
135
|
},
|
|
100
136
|
};
|
|
101
137
|
}
|
|
@@ -103,7 +139,7 @@ function validateCodexIntegration(options = {}) {
|
|
|
103
139
|
function formatHumanReport(result) {
|
|
104
140
|
if (result.ok) {
|
|
105
141
|
const lines = [
|
|
106
|
-
`✅ Codex integration validation passed (agents: ${result.metrics.codexAgents}, skills: ${result.metrics.codexSkills})`,
|
|
142
|
+
`✅ Codex integration validation passed (agents: ${result.metrics.codexAgents} resolve, ${result.metrics.orphans} orphans, ${result.metrics.brokenPointers} broken pointers, skills: ${result.metrics.codexSkills})`,
|
|
107
143
|
];
|
|
108
144
|
if (result.warnings.length > 0) {
|
|
109
145
|
lines.push(...result.warnings.map((w) => `⚠️ ${w}`));
|