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
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Send event to SINAPSE Monitor server.
|
|
4
|
-
Non-blocking with short timeout to avoid slowing Claude.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import json
|
|
8
|
-
import os
|
|
9
|
-
import time
|
|
10
|
-
import urllib.request
|
|
11
|
-
from typing import Any
|
|
12
|
-
|
|
13
|
-
SERVER_URL = os.environ.get("SINAPSE_MONITOR_URL", "http://localhost:4001")
|
|
14
|
-
TIMEOUT_MS = int(os.environ.get("SINAPSE_MONITOR_TIMEOUT_MS", "500"))
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def send_event(event_type: str, data: dict[str, Any]) -> bool:
|
|
18
|
-
"""
|
|
19
|
-
Send event to SINAPSE Monitor server.
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
event_type: Hook event type (PreToolUse, PostToolUse, etc.)
|
|
23
|
-
data: Event data from Claude hook
|
|
24
|
-
|
|
25
|
-
Returns:
|
|
26
|
-
True if sent successfully, False otherwise
|
|
27
|
-
"""
|
|
28
|
-
try:
|
|
29
|
-
payload = json.dumps({
|
|
30
|
-
"type": event_type,
|
|
31
|
-
"timestamp": int(time.time() * 1000),
|
|
32
|
-
"data": data
|
|
33
|
-
}).encode("utf-8")
|
|
34
|
-
|
|
35
|
-
req = urllib.request.Request(
|
|
36
|
-
f"{SERVER_URL}/events",
|
|
37
|
-
data=payload,
|
|
38
|
-
headers={"Content-Type": "application/json"},
|
|
39
|
-
method="POST"
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
urllib.request.urlopen(req, timeout=TIMEOUT_MS / 1000)
|
|
43
|
-
return True
|
|
44
|
-
|
|
45
|
-
except Exception:
|
|
46
|
-
# Silent fail - never block Claude
|
|
47
|
-
return False
|
|
48
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Notification hook - captures Claude notifications.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import json
|
|
7
|
-
import sys
|
|
8
|
-
import os
|
|
9
|
-
|
|
10
|
-
# Add lib to path
|
|
11
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
12
|
-
|
|
13
|
-
from lib.send_event import send_event
|
|
14
|
-
from lib.enrich import enrich_event
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def main():
|
|
18
|
-
# Read event from stdin
|
|
19
|
-
data = json.load(sys.stdin)
|
|
20
|
-
|
|
21
|
-
# Enrich with SINAPSE context
|
|
22
|
-
data = enrich_event(data)
|
|
23
|
-
|
|
24
|
-
# Send to monitor server
|
|
25
|
-
send_event("Notification", data)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if __name__ == "__main__":
|
|
29
|
-
main()
|
|
30
|
-
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
PostToolUse hook - captures tool results after execution.
|
|
4
|
-
|
|
5
|
-
This hook runs after Claude executes any tool, capturing the result.
|
|
6
|
-
Most important for tracking what actually happened.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
import sys
|
|
11
|
-
import os
|
|
12
|
-
|
|
13
|
-
# Add lib to path
|
|
14
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
15
|
-
|
|
16
|
-
from lib.send_event import send_event
|
|
17
|
-
from lib.enrich import enrich_event
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def main():
|
|
21
|
-
# Read event from stdin
|
|
22
|
-
data = json.load(sys.stdin)
|
|
23
|
-
|
|
24
|
-
# Truncate large fields
|
|
25
|
-
if "tool_result" in data:
|
|
26
|
-
result = data["tool_result"]
|
|
27
|
-
if isinstance(result, str) and len(result) > 1000:
|
|
28
|
-
data["tool_result"] = result[:1000] + "...[truncated]"
|
|
29
|
-
|
|
30
|
-
if "tool_input" in data:
|
|
31
|
-
tool_input = data["tool_input"]
|
|
32
|
-
if isinstance(tool_input, dict):
|
|
33
|
-
for key, value in tool_input.items():
|
|
34
|
-
if isinstance(value, str) and len(value) > 500:
|
|
35
|
-
data["tool_input"][key] = value[:500] + "..."
|
|
36
|
-
|
|
37
|
-
# Enrich with SINAPSE context
|
|
38
|
-
data = enrich_event(data)
|
|
39
|
-
|
|
40
|
-
# Send to monitor server
|
|
41
|
-
send_event("PostToolUse", data)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if __name__ == "__main__":
|
|
45
|
-
main()
|
|
46
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
PreCompact hook - captures before context compaction.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import json
|
|
7
|
-
import sys
|
|
8
|
-
import os
|
|
9
|
-
|
|
10
|
-
# Add lib to path
|
|
11
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
12
|
-
|
|
13
|
-
from lib.send_event import send_event
|
|
14
|
-
from lib.enrich import enrich_event
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def main():
|
|
18
|
-
# Read event from stdin
|
|
19
|
-
data = json.load(sys.stdin)
|
|
20
|
-
|
|
21
|
-
# Enrich with SINAPSE context
|
|
22
|
-
data = enrich_event(data)
|
|
23
|
-
|
|
24
|
-
# Send to monitor server
|
|
25
|
-
send_event("PreCompact", data)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if __name__ == "__main__":
|
|
29
|
-
main()
|
|
30
|
-
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
PreToolUse hook - captures tool calls before execution.
|
|
4
|
-
|
|
5
|
-
This hook runs before Claude executes any tool (Read, Write, Bash, etc.)
|
|
6
|
-
Use this to see what tools are being invoked and their inputs.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
import sys
|
|
11
|
-
import os
|
|
12
|
-
|
|
13
|
-
# Add lib to path
|
|
14
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
15
|
-
|
|
16
|
-
from lib.send_event import send_event
|
|
17
|
-
from lib.enrich import enrich_event
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def main():
|
|
21
|
-
# Read event from stdin
|
|
22
|
-
data = json.load(sys.stdin)
|
|
23
|
-
|
|
24
|
-
# Truncate large fields to avoid memory issues
|
|
25
|
-
if "tool_input" in data:
|
|
26
|
-
tool_input = data["tool_input"]
|
|
27
|
-
if isinstance(tool_input, dict):
|
|
28
|
-
for key, value in tool_input.items():
|
|
29
|
-
if isinstance(value, str) and len(value) > 500:
|
|
30
|
-
data["tool_input"][key] = value[:500] + "..."
|
|
31
|
-
|
|
32
|
-
# Enrich with SINAPSE context
|
|
33
|
-
data = enrich_event(data)
|
|
34
|
-
|
|
35
|
-
# Send to monitor server
|
|
36
|
-
send_event("PreToolUse", data)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if __name__ == "__main__":
|
|
40
|
-
main()
|
|
41
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Stop hook - captures when Claude stops execution.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import json
|
|
7
|
-
import sys
|
|
8
|
-
import os
|
|
9
|
-
|
|
10
|
-
# Add lib to path
|
|
11
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
12
|
-
|
|
13
|
-
from lib.send_event import send_event
|
|
14
|
-
from lib.enrich import enrich_event
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def main():
|
|
18
|
-
# Read event from stdin
|
|
19
|
-
data = json.load(sys.stdin)
|
|
20
|
-
|
|
21
|
-
# Enrich with SINAPSE context
|
|
22
|
-
data = enrich_event(data)
|
|
23
|
-
|
|
24
|
-
# Send to monitor server
|
|
25
|
-
send_event("Stop", data)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if __name__ == "__main__":
|
|
29
|
-
main()
|
|
30
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
SubagentStop hook - captures when a subagent (Task tool) stops.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import json
|
|
7
|
-
import sys
|
|
8
|
-
import os
|
|
9
|
-
|
|
10
|
-
# Add lib to path
|
|
11
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
12
|
-
|
|
13
|
-
from lib.send_event import send_event
|
|
14
|
-
from lib.enrich import enrich_event
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def main():
|
|
18
|
-
# Read event from stdin
|
|
19
|
-
data = json.load(sys.stdin)
|
|
20
|
-
|
|
21
|
-
# Enrich with SINAPSE context
|
|
22
|
-
data = enrich_event(data)
|
|
23
|
-
|
|
24
|
-
# Send to monitor server
|
|
25
|
-
send_event("SubagentStop", data)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if __name__ == "__main__":
|
|
29
|
-
main()
|
|
30
|
-
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
UserPromptSubmit hook - captures when user sends a prompt.
|
|
4
|
-
|
|
5
|
-
This is the starting point of each interaction.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import json
|
|
9
|
-
import sys
|
|
10
|
-
import os
|
|
11
|
-
|
|
12
|
-
# Add lib to path
|
|
13
|
-
sys.path.insert(0, os.path.dirname(__file__))
|
|
14
|
-
|
|
15
|
-
from lib.send_event import send_event
|
|
16
|
-
from lib.enrich import enrich_event
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def main():
|
|
20
|
-
# Read event from stdin
|
|
21
|
-
data = json.load(sys.stdin)
|
|
22
|
-
|
|
23
|
-
# Store user prompt for agent detection
|
|
24
|
-
if "user_prompt" in data:
|
|
25
|
-
# Truncate if too long
|
|
26
|
-
prompt = data["user_prompt"]
|
|
27
|
-
if isinstance(prompt, str) and len(prompt) > 1000:
|
|
28
|
-
data["user_prompt"] = prompt[:1000] + "..."
|
|
29
|
-
|
|
30
|
-
# Enrich with SINAPSE context
|
|
31
|
-
data = enrich_event(data)
|
|
32
|
-
|
|
33
|
-
# Send to monitor server
|
|
34
|
-
send_event("UserPromptSubmit", data)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if __name__ == "__main__":
|
|
38
|
-
main()
|
|
39
|
-
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# SINAPSE Agent/Squad Tracker for Claude Code Statusline
|
|
3
|
-
# Called via Claude Code UserPromptSubmit hook
|
|
4
|
-
#
|
|
5
|
-
# Detects @agent, /squad:command, /ns:agents:name activations
|
|
6
|
-
# Writes to ~/.claude/session-cache/ for statusline-script.js to read
|
|
7
|
-
#
|
|
8
|
-
# Installed automatically by `npx sinapse-ai install`
|
|
9
|
-
# Source: .sinapse-ai/product/templates/statusline/
|
|
10
|
-
|
|
11
|
-
INPUT=$(cat)
|
|
12
|
-
|
|
13
|
-
node -e "
|
|
14
|
-
const fs = require('fs');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const os = require('os');
|
|
17
|
-
|
|
18
|
-
let prompt = '';
|
|
19
|
-
try {
|
|
20
|
-
const j = JSON.parse(process.argv[1]);
|
|
21
|
-
prompt = j.prompt || j.message || '';
|
|
22
|
-
} catch {}
|
|
23
|
-
if (!prompt) process.exit(0);
|
|
24
|
-
|
|
25
|
-
function simpleHash(str) {
|
|
26
|
-
let h = 0;
|
|
27
|
-
for (let i = 0; i < str.length; i++) {
|
|
28
|
-
h = ((h << 5) - h) + str.charCodeAt(i);
|
|
29
|
-
h |= 0;
|
|
30
|
-
}
|
|
31
|
-
return Math.abs(h).toString(16);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const cacheDir = path.join(os.homedir(), '.claude', 'session-cache');
|
|
35
|
-
try { fs.mkdirSync(cacheDir, { recursive: true }); } catch {}
|
|
36
|
-
|
|
37
|
-
const hash = simpleHash(process.cwd());
|
|
38
|
-
const cacheFile = path.join(cacheDir, hash + '.json');
|
|
39
|
-
|
|
40
|
-
let agent = '', squad = '';
|
|
41
|
-
try {
|
|
42
|
-
const c = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
43
|
-
agent = c.agent || '';
|
|
44
|
-
squad = c.squad || '';
|
|
45
|
-
} catch {}
|
|
46
|
-
|
|
47
|
-
let changed = false;
|
|
48
|
-
|
|
49
|
-
if (/^\*exit\b/.test(prompt)) {
|
|
50
|
-
agent = ''; squad = '';
|
|
51
|
-
changed = true;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const agentMatch = prompt.match(/@([a-zA-Z_-]+)/);
|
|
55
|
-
if (agentMatch) { agent = agentMatch[1]; changed = true; }
|
|
56
|
-
|
|
57
|
-
const nsMatch = prompt.match(/\/[a-zA-Z_-]+:agents:([a-zA-Z_-]+)/);
|
|
58
|
-
if (nsMatch) { agent = nsMatch[1]; changed = true; }
|
|
59
|
-
|
|
60
|
-
const squadMatch = prompt.match(/\/([a-zA-Z_-]+):[a-zA-Z_-]+/);
|
|
61
|
-
if (squadMatch && !/:agents:/.test(squadMatch[0])) { squad = squadMatch[1]; changed = true; }
|
|
62
|
-
|
|
63
|
-
if (changed) {
|
|
64
|
-
fs.writeFileSync(cacheFile, JSON.stringify({ agent, squad, updated: new Date().toISOString() }));
|
|
65
|
-
}
|
|
66
|
-
" "$INPUT"
|
|
67
|
-
|
|
68
|
-
exit 0
|
|
69
|
-
|
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Unit tests for ConfidenceScorer
|
|
3
|
-
* @story WIS-2 - Workflow Registry Enhancement
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
ConfidenceScorer,
|
|
10
|
-
createConfidenceScorer,
|
|
11
|
-
SCORING_WEIGHTS,
|
|
12
|
-
} = require('../engine/confidence-scorer');
|
|
13
|
-
|
|
14
|
-
describe('ConfidenceScorer', () => {
|
|
15
|
-
let scorer;
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
scorer = createConfidenceScorer();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe('constructor', () => {
|
|
22
|
-
it('should create scorer with default weights', () => {
|
|
23
|
-
const weights = scorer.getWeights();
|
|
24
|
-
expect(weights.COMMAND_MATCH).toBe(0.4);
|
|
25
|
-
expect(weights.AGENT_MATCH).toBe(0.25);
|
|
26
|
-
expect(weights.HISTORY_DEPTH).toBe(0.2);
|
|
27
|
-
expect(weights.PROJECT_STATE).toBe(0.15);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should accept custom weights', () => {
|
|
31
|
-
const customScorer = createConfidenceScorer({
|
|
32
|
-
weights: {
|
|
33
|
-
COMMAND_MATCH: 0.5,
|
|
34
|
-
AGENT_MATCH: 0.2,
|
|
35
|
-
HISTORY_DEPTH: 0.15,
|
|
36
|
-
PROJECT_STATE: 0.15,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
const weights = customScorer.getWeights();
|
|
40
|
-
expect(weights.COMMAND_MATCH).toBe(0.5);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should throw error if weights do not sum to 1.0', () => {
|
|
44
|
-
expect(() => {
|
|
45
|
-
createConfidenceScorer({
|
|
46
|
-
weights: {
|
|
47
|
-
COMMAND_MATCH: 0.5,
|
|
48
|
-
AGENT_MATCH: 0.5,
|
|
49
|
-
HISTORY_DEPTH: 0.2,
|
|
50
|
-
PROJECT_STATE: 0.15,
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
}).toThrow('Scoring weights must sum to 1.0');
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('score()', () => {
|
|
58
|
-
it('should return 0 for null suggestion', () => {
|
|
59
|
-
const result = scorer.score(null, { lastCommand: 'test' });
|
|
60
|
-
expect(result).toBe(0);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should return 0 for null context', () => {
|
|
64
|
-
const result = scorer.score({ trigger: 'test' }, null);
|
|
65
|
-
expect(result).toBe(0);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should return high score for exact command match', () => {
|
|
69
|
-
const suggestion = {
|
|
70
|
-
trigger: 'create-epic',
|
|
71
|
-
agentSequence: ['po', 'sm'],
|
|
72
|
-
keyCommands: ['create-epic', 'create-story'],
|
|
73
|
-
};
|
|
74
|
-
const context = {
|
|
75
|
-
lastCommand: 'create-epic',
|
|
76
|
-
lastCommands: ['create-epic'],
|
|
77
|
-
agentId: '@po',
|
|
78
|
-
projectState: {},
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const result = scorer.score(suggestion, context);
|
|
82
|
-
// Score is composed of: command(40%) + agent(25%) + history(20%) + state(15%)
|
|
83
|
-
expect(result).toBeGreaterThanOrEqual(0.7);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should return medium score for partial command match', () => {
|
|
87
|
-
const suggestion = {
|
|
88
|
-
trigger: 'create-epic',
|
|
89
|
-
agentSequence: ['po', 'sm'],
|
|
90
|
-
keyCommands: ['create-epic', 'create-story'],
|
|
91
|
-
};
|
|
92
|
-
const context = {
|
|
93
|
-
lastCommand: 'create-story',
|
|
94
|
-
lastCommands: ['create-story'],
|
|
95
|
-
agentId: '@sm',
|
|
96
|
-
projectState: {},
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const result = scorer.score(suggestion, context);
|
|
100
|
-
expect(result).toBeGreaterThan(0.4);
|
|
101
|
-
expect(result).toBeLessThan(0.8);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('should return low score for no command match', () => {
|
|
105
|
-
const suggestion = {
|
|
106
|
-
trigger: 'create-epic',
|
|
107
|
-
agentSequence: ['po', 'sm'],
|
|
108
|
-
keyCommands: ['create-epic', 'create-story'],
|
|
109
|
-
};
|
|
110
|
-
const context = {
|
|
111
|
-
lastCommand: 'push',
|
|
112
|
-
lastCommands: ['push'],
|
|
113
|
-
agentId: '@devops',
|
|
114
|
-
projectState: {},
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const result = scorer.score(suggestion, context);
|
|
118
|
-
expect(result).toBeLessThanOrEqual(0.3);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should return normalized score between 0 and 1', () => {
|
|
122
|
-
const suggestion = { trigger: 'any', agentSequence: [], keyCommands: [] };
|
|
123
|
-
const context = { lastCommand: 'any', lastCommands: [], agentId: '' };
|
|
124
|
-
|
|
125
|
-
const result = scorer.score(suggestion, context);
|
|
126
|
-
expect(result).toBeGreaterThanOrEqual(0);
|
|
127
|
-
expect(result).toBeLessThanOrEqual(1);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe('matchCommand()', () => {
|
|
132
|
-
it('should return 1.0 for exact match', () => {
|
|
133
|
-
const result = scorer.matchCommand('create-epic', 'create-epic');
|
|
134
|
-
expect(result).toBe(1.0);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should return 1.0 when normalized trigger equals command', () => {
|
|
138
|
-
// "create-epic completed" normalizes to "create-epic"
|
|
139
|
-
const result = scorer.matchCommand('create-epic completed', 'create-epic');
|
|
140
|
-
expect(result).toBe(1.0);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('should return partial score for keyword match', () => {
|
|
144
|
-
const result = scorer.matchCommand('create-epic', 'create-story');
|
|
145
|
-
// Both share "create" word, so partial match
|
|
146
|
-
expect(result).toBeGreaterThan(0);
|
|
147
|
-
expect(result).toBeLessThan(1);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('should return 0 for no match', () => {
|
|
151
|
-
const result = scorer.matchCommand('create-epic', 'push');
|
|
152
|
-
expect(result).toBe(0);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('should handle null trigger', () => {
|
|
156
|
-
const result = scorer.matchCommand(null, 'test');
|
|
157
|
-
expect(result).toBe(0);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it('should handle null command', () => {
|
|
161
|
-
const result = scorer.matchCommand('test', null);
|
|
162
|
-
expect(result).toBe(0);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('matchAgent()', () => {
|
|
167
|
-
it('should return high score for first agent in sequence', () => {
|
|
168
|
-
const result = scorer.matchAgent(['po', 'sm', 'dev'], '@po');
|
|
169
|
-
expect(result).toBeGreaterThan(0.6);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it('should return higher score for later agents', () => {
|
|
173
|
-
const result1 = scorer.matchAgent(['po', 'sm', 'dev'], '@po');
|
|
174
|
-
const result2 = scorer.matchAgent(['po', 'sm', 'dev'], '@dev');
|
|
175
|
-
expect(result2).toBeGreaterThan(result1);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it('should return 0 for agent not in sequence', () => {
|
|
179
|
-
const result = scorer.matchAgent(['po', 'sm'], '@devops');
|
|
180
|
-
expect(result).toBe(0);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it('should handle agent with @ prefix', () => {
|
|
184
|
-
const result = scorer.matchAgent(['po'], '@po');
|
|
185
|
-
expect(result).toBeGreaterThan(0);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should handle null agent sequence', () => {
|
|
189
|
-
const result = scorer.matchAgent(null, '@po');
|
|
190
|
-
expect(result).toBe(0);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
describe('matchHistory()', () => {
|
|
195
|
-
it('should return high score when history matches key commands', () => {
|
|
196
|
-
const keyCommands = ['create-epic', 'create-story'];
|
|
197
|
-
const history = ['create-epic', 'create-story', 'validate'];
|
|
198
|
-
|
|
199
|
-
const result = scorer.matchHistory(keyCommands, history);
|
|
200
|
-
expect(result).toBeGreaterThan(0.8);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it('should give recency bonus for recent commands', () => {
|
|
204
|
-
const keyCommands = ['create-epic'];
|
|
205
|
-
const historyRecent = ['create-epic', 'other', 'another'];
|
|
206
|
-
const historyOld = ['other', 'another', 'create-epic'];
|
|
207
|
-
|
|
208
|
-
const resultRecent = scorer.matchHistory(keyCommands, historyRecent);
|
|
209
|
-
const resultOld = scorer.matchHistory(keyCommands, historyOld);
|
|
210
|
-
|
|
211
|
-
// Recent should get higher score due to recency bonus
|
|
212
|
-
expect(resultRecent).toBeGreaterThanOrEqual(resultOld);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it('should return 0 for no matching commands', () => {
|
|
216
|
-
const keyCommands = ['create-epic'];
|
|
217
|
-
const history = ['push', 'commit'];
|
|
218
|
-
|
|
219
|
-
const result = scorer.matchHistory(keyCommands, history);
|
|
220
|
-
expect(result).toBe(0);
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it('should handle empty history', () => {
|
|
224
|
-
const result = scorer.matchHistory(['test'], []);
|
|
225
|
-
expect(result).toBe(0);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it('should handle empty key commands', () => {
|
|
229
|
-
const result = scorer.matchHistory([], ['test']);
|
|
230
|
-
expect(result).toBe(0);
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
describe('matchProjectState()', () => {
|
|
235
|
-
it('should return neutral score for empty state', () => {
|
|
236
|
-
const result = scorer.matchProjectState({}, {});
|
|
237
|
-
expect(result).toBe(0.5);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('should boost score for git-related suggestions when uncommitted changes', () => {
|
|
241
|
-
const suggestion = { trigger: 'git commit' };
|
|
242
|
-
const state = { hasUncommittedChanges: true };
|
|
243
|
-
|
|
244
|
-
const result = scorer.matchProjectState(suggestion, state);
|
|
245
|
-
expect(result).toBeGreaterThan(0.5);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('should boost score for test suggestions when tests failing', () => {
|
|
249
|
-
const suggestion = { trigger: 'run tests' };
|
|
250
|
-
const state = { failingTests: true };
|
|
251
|
-
|
|
252
|
-
const result = scorer.matchProjectState(suggestion, state);
|
|
253
|
-
expect(result).toBeGreaterThan(0.5);
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('should return 0.5 for null project state', () => {
|
|
257
|
-
const result = scorer.matchProjectState({}, null);
|
|
258
|
-
expect(result).toBe(0.5);
|
|
259
|
-
});
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
describe('normalizeCommand()', () => {
|
|
263
|
-
it('should convert to lowercase', () => {
|
|
264
|
-
const result = scorer.normalizeCommand('CREATE-EPIC');
|
|
265
|
-
expect(result).toBe('create-epic');
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('should remove "completed" suffix', () => {
|
|
269
|
-
const result = scorer.normalizeCommand('create-epic completed');
|
|
270
|
-
expect(result).toBe('create-epic');
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it('should remove "successfully" suffix', () => {
|
|
274
|
-
const result = scorer.normalizeCommand('create-epic successfully');
|
|
275
|
-
expect(result).toBe('create-epic');
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it('should remove * prefix', () => {
|
|
279
|
-
const result = scorer.normalizeCommand('*create-epic');
|
|
280
|
-
expect(result).toBe('create-epic');
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
it('should handle null', () => {
|
|
284
|
-
const result = scorer.normalizeCommand(null);
|
|
285
|
-
expect(result).toBe('');
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
describe('rankSuggestions()', () => {
|
|
290
|
-
it('should return empty array for empty suggestions', () => {
|
|
291
|
-
const result = scorer.rankSuggestions([], {});
|
|
292
|
-
expect(result).toEqual([]);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
it('should rank suggestions by score descending', () => {
|
|
296
|
-
const suggestions = [
|
|
297
|
-
{ trigger: 'push', agentSequence: ['devops'] },
|
|
298
|
-
{ trigger: 'create-epic', agentSequence: ['po'] },
|
|
299
|
-
];
|
|
300
|
-
const context = {
|
|
301
|
-
lastCommand: 'create-epic',
|
|
302
|
-
lastCommands: ['create-epic'],
|
|
303
|
-
agentId: '@po',
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
const result = scorer.rankSuggestions(suggestions, context);
|
|
307
|
-
expect(result[0].trigger).toBe('create-epic');
|
|
308
|
-
expect(result[0].score).toBeGreaterThan(result[1].score);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
it('should add score property to each suggestion', () => {
|
|
312
|
-
const suggestions = [{ trigger: 'test' }];
|
|
313
|
-
const context = { lastCommand: 'test' };
|
|
314
|
-
|
|
315
|
-
const result = scorer.rankSuggestions(suggestions, context);
|
|
316
|
-
expect(result[0]).toHaveProperty('score');
|
|
317
|
-
expect(typeof result[0].score).toBe('number');
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
describe('SCORING_WEIGHTS constant', () => {
|
|
322
|
-
it('should have correct default weights', () => {
|
|
323
|
-
expect(SCORING_WEIGHTS.COMMAND_MATCH).toBe(0.4);
|
|
324
|
-
expect(SCORING_WEIGHTS.AGENT_MATCH).toBe(0.25);
|
|
325
|
-
expect(SCORING_WEIGHTS.HISTORY_DEPTH).toBe(0.2);
|
|
326
|
-
expect(SCORING_WEIGHTS.PROJECT_STATE).toBe(0.15);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it('should sum to 1.0', () => {
|
|
330
|
-
const sum = Object.values(SCORING_WEIGHTS).reduce((a, b) => a + b, 0);
|
|
331
|
-
expect(sum).toBe(1.0);
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
});
|
|
335
|
-
|