@jaimevalasek/aioson 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/README.md +153 -10
- package/docs/en/cli-reference.md +56 -1
- package/docs/en/i18n.md +18 -18
- package/docs/en/schemas/index.json +10 -0
- package/docs/en/schemas/parallel-assign.schema.json +9 -0
- package/docs/en/schemas/parallel-doctor.schema.json +36 -0
- package/docs/en/schemas/parallel-guard.schema.json +63 -0
- package/docs/en/schemas/parallel-merge.schema.json +84 -0
- package/docs/en/schemas/parallel-status.schema.json +91 -1
- package/docs/integrations/apps-publish-marketplace.md +94 -0
- package/docs/pt/README.md +9 -0
- package/docs/pt/agentes.md +324 -3
- package/docs/pt/clientes-ai.md +7 -3
- package/docs/pt/comandos-cli.md +160 -13
- package/docs/pt/compress-agents.md +304 -0
- package/docs/pt/design-docs-governance.md +59 -0
- package/docs/pt/feature-archive.md +191 -0
- package/docs/pt/genome-3.0-spec.md +115 -4
- package/docs/pt/genome-distribution.md +232 -0
- package/docs/pt/inicio-rapido.md +1 -0
- package/docs/pt/motor-hardening.md +492 -0
- package/docs/pt/runner-system.md +113 -0
- package/package.json +2 -1
- package/src/agent-manifests.js +66 -0
- package/src/agents.js +27 -7
- package/src/autonomy-policy.js +139 -0
- package/src/brain-query.js +161 -0
- package/src/cli.js +1377 -1099
- package/src/commands/agents.js +102 -7
- package/src/commands/artifact-validate.js +33 -4
- package/src/commands/auth.js +272 -0
- package/src/commands/brain-query.js +44 -0
- package/src/commands/briefing.js +344 -0
- package/src/commands/commit-prepare.js +547 -0
- package/src/commands/compress-agents.js +416 -0
- package/src/commands/context-health.js +4 -2
- package/src/commands/context-trim.js +17 -11
- package/src/commands/design-hybrid-options.js +3 -3
- package/src/commands/devlog-process.js +6 -4
- package/src/commands/dossier.js +423 -0
- package/src/commands/feature-archive.js +513 -0
- package/src/commands/feature-close.js +123 -18
- package/src/commands/gate-approve.js +198 -0
- package/src/commands/gate-check.js +24 -5
- package/src/commands/genome-doctor.js +166 -9
- package/src/commands/git-guard.js +170 -0
- package/src/commands/harness.js +121 -0
- package/src/commands/implementation-plan.js +47 -20
- package/src/commands/init.js +6 -2
- package/src/commands/install.js +6 -2
- package/src/commands/live.js +497 -56
- package/src/commands/locale-apply.js +9 -6
- package/src/commands/locale-diff.js +11 -112
- package/src/commands/mcp-doctor.js +2 -1
- package/src/commands/mcp-init.js +4 -10
- package/src/commands/memory.js +234 -0
- package/src/commands/parallel-assign.js +107 -27
- package/src/commands/parallel-doctor.js +416 -3
- package/src/commands/parallel-guard.js +241 -0
- package/src/commands/parallel-init.js +66 -4
- package/src/commands/parallel-merge.js +299 -0
- package/src/commands/parallel-status.js +147 -3
- package/src/commands/preflight.js +63 -4
- package/src/commands/qa-init.js +10 -5
- package/src/commands/revision.js +235 -0
- package/src/commands/scaffold-complete.js +188 -0
- package/src/commands/security-audit.js +275 -0
- package/src/commands/security-scan.js +376 -0
- package/src/commands/self-implement-loop.js +46 -2
- package/src/commands/setup-context.js +11 -10
- package/src/commands/squad-agent-create.js +51 -9
- package/src/commands/squad-investigate.js +53 -0
- package/src/commands/squad-plan.js +33 -1
- package/src/commands/squad-scaffold.js +4 -3
- package/src/commands/squad-score.js +71 -14
- package/src/commands/squad-status.js +22 -1
- package/src/commands/squad-validate.js +93 -2
- package/src/commands/store-genome.js +304 -0
- package/src/commands/store-skill.js +247 -0
- package/src/commands/store-squad.js +431 -0
- package/src/commands/store-system.js +392 -0
- package/src/commands/tool-capabilities.js +63 -0
- package/src/commands/update.js +3 -3
- package/src/commands/verify-gate.js +40 -0
- package/src/commands/workflow-execute.js +644 -155
- package/src/commands/workflow-harden.js +231 -0
- package/src/commands/workflow-heal.js +136 -0
- package/src/commands/workflow-next.js +460 -22
- package/src/commands/workflow-status.js +328 -138
- package/src/commands/workspace.js +144 -0
- package/src/constants.js +55 -75
- package/src/context-memory.js +133 -4
- package/src/context-writer.js +2 -1
- package/src/context.js +32 -2
- package/src/doctor.js +46 -6
- package/src/dossier/codemap-store.js +267 -0
- package/src/dossier/dossier-bootstrap.js +222 -0
- package/src/dossier/dossier-compact.js +159 -0
- package/src/dossier/lock.js +128 -0
- package/src/dossier/revision-store.js +313 -0
- package/src/dossier/schema.js +155 -0
- package/src/dossier/store.js +400 -0
- package/src/execution-gateway.js +3 -0
- package/src/friction-scanner.js +202 -0
- package/src/genome-schema.js +24 -1
- package/src/genomes.js +33 -0
- package/src/handoff-contract.js +363 -0
- package/src/handoff-validator.js +45 -0
- package/src/harness/circuit-breaker.js +135 -0
- package/src/i18n/messages/en.js +317 -22
- package/src/i18n/messages/es.js +259 -18
- package/src/i18n/messages/fr.js +260 -18
- package/src/i18n/messages/pt-BR.js +313 -22
- package/src/install-profile.js +0 -16
- package/src/installer.js +70 -6
- package/src/lib/git-commit-guard.js +691 -0
- package/src/lib/security/artifact-reader.js +167 -0
- package/src/lib/security/exit-codes.js +51 -0
- package/src/lib/security/findings-writer.js +176 -0
- package/src/lib/security/runtime-events.js +77 -0
- package/src/lib/security/secrets-regex.js +115 -0
- package/src/lib/store/security-scan.js +173 -0
- package/src/lib/terminal-checkbox.js +130 -0
- package/src/lib/tmux-launcher.js +163 -0
- package/src/lib/tool-capabilities.js +102 -0
- package/src/locales.js +12 -8
- package/src/parallel-workspace.js +756 -0
- package/src/parser.js +8 -1
- package/src/path-guard.js +47 -0
- package/src/preflight-engine.js +237 -26
- package/src/self-healing.js +142 -0
- package/src/session-handoff.js +111 -1
- package/src/squad/squad-scaffold.js +183 -19
- package/src/test-briefing.js +226 -0
- package/src/updater.js +1 -1
- package/src/utils.js +3 -0
- package/src/workflow-gates.js +185 -0
- package/template/.aioson/agents/analyst.md +76 -130
- package/template/.aioson/agents/architect.md +53 -86
- package/template/.aioson/agents/committer.md +161 -0
- package/template/.aioson/agents/copywriter.md +463 -0
- package/template/.aioson/agents/cypher.md +252 -0
- package/template/.aioson/agents/dev.md +112 -600
- package/template/.aioson/agents/deyvin.md +33 -235
- package/template/.aioson/agents/discover.md +235 -0
- package/template/.aioson/agents/discovery-design-doc.md +17 -252
- package/template/.aioson/agents/genome.md +76 -26
- package/template/.aioson/agents/manifests/analyst.manifest.json +26 -0
- package/template/.aioson/agents/manifests/architect.manifest.json +23 -0
- package/template/.aioson/agents/manifests/committer.manifest.json +23 -0
- package/template/.aioson/agents/manifests/dev.manifest.json +37 -0
- package/template/.aioson/agents/manifests/orchestrator.manifest.json +30 -0
- package/template/.aioson/agents/manifests/pentester.manifest.json +39 -0
- package/template/.aioson/agents/manifests/pm.manifest.json +26 -0
- package/template/.aioson/agents/manifests/product.manifest.json +23 -0
- package/template/.aioson/agents/manifests/qa.manifest.json +25 -0
- package/template/.aioson/agents/manifests/setup.manifest.json +20 -0
- package/template/.aioson/agents/manifests/ux-ui.manifest.json +24 -0
- package/template/.aioson/agents/neo.md +10 -8
- package/template/.aioson/agents/orache.md +2 -6
- package/template/.aioson/agents/orchestrator.md +81 -182
- package/template/.aioson/agents/pentester.md +235 -0
- package/template/.aioson/agents/pm.md +40 -104
- package/template/.aioson/agents/product.md +99 -344
- package/template/.aioson/agents/profiler-enricher.md +57 -6
- package/template/.aioson/agents/profiler-forge.md +17 -7
- package/template/.aioson/agents/profiler-researcher.md +29 -6
- package/template/.aioson/agents/qa.md +165 -410
- package/template/.aioson/agents/setup.md +52 -262
- package/template/.aioson/agents/sheldon.md +122 -754
- package/template/.aioson/agents/site-forge.md +111 -1583
- package/template/.aioson/agents/squad.md +139 -1820
- package/template/.aioson/agents/tester.md +10 -0
- package/template/.aioson/agents/ux-ui.md +103 -645
- package/template/.aioson/agents/validator.md +69 -0
- package/template/.aioson/brains/scripts/query.js +5 -1
- package/template/.aioson/config/autonomy-protocol.json +43 -0
- package/template/.aioson/config.md +43 -15
- package/template/.aioson/constitution.md +36 -33
- package/template/.aioson/context/design-doc.md +136 -0
- package/template/.aioson/context/project-map.md +57 -0
- package/template/.aioson/design-docs/code-reuse.md +48 -0
- package/template/.aioson/design-docs/componentization.md +47 -0
- package/template/.aioson/design-docs/file-size.md +52 -0
- package/template/.aioson/design-docs/folder-structure.md +51 -0
- package/template/.aioson/design-docs/naming.md +54 -0
- package/template/.aioson/docs/LAYERS.md +12 -2
- package/template/.aioson/docs/dev/execution-discipline.md +106 -0
- package/template/.aioson/docs/dev/stack-conventions.md +83 -0
- package/template/.aioson/docs/deyvin/continuity-recovery.md +57 -0
- package/template/.aioson/docs/deyvin/debugging-escalation.md +30 -0
- package/template/.aioson/docs/deyvin/pair-execution.md +44 -0
- package/template/.aioson/docs/deyvin/runtime-handoffs.md +36 -0
- package/template/.aioson/docs/product/conversation-playbook.md +116 -0
- package/template/.aioson/docs/product/prd-contract.md +107 -0
- package/template/.aioson/docs/product/quality-lens.md +57 -0
- package/template/.aioson/docs/product/research-loop.md +65 -0
- package/template/.aioson/docs/sheldon/enrichment-paths.md +134 -0
- package/template/.aioson/docs/sheldon/quality-lens.md +57 -0
- package/template/.aioson/docs/sheldon/research-loop.md +56 -0
- package/template/.aioson/docs/sheldon/web-intelligence.md +75 -0
- package/template/.aioson/docs/site-forge-build.md +195 -0
- package/template/.aioson/docs/site-forge-extraction.md +135 -0
- package/template/.aioson/docs/site-forge-qa.md +155 -0
- package/template/.aioson/docs/site-forge-recon.md +434 -0
- package/template/.aioson/docs/site-forge-transform.md +249 -0
- package/template/.aioson/docs/squad/content-output.md +91 -0
- package/template/.aioson/docs/squad/creation-flow.md +135 -0
- package/template/.aioson/docs/squad/domain-classification.md +117 -0
- package/template/.aioson/docs/squad/genome-bindings.md +47 -0
- package/template/.aioson/docs/squad/package-contract.md +234 -0
- package/template/.aioson/docs/squad/quality-lens.md +56 -0
- package/template/.aioson/docs/squad/research-loop.md +59 -0
- package/template/.aioson/docs/squad/session-operations.md +117 -0
- package/template/.aioson/docs/squad/workflow-quality.md +165 -0
- package/template/.aioson/docs/ux-ui/accessibility-audit.md +55 -0
- package/template/.aioson/docs/ux-ui/audit-mode.md +86 -0
- package/template/.aioson/docs/ux-ui/component-map.md +35 -0
- package/template/.aioson/docs/ux-ui/design-execution.md +111 -0
- package/template/.aioson/docs/ux-ui/design-gate.md +27 -0
- package/template/.aioson/docs/ux-ui/research-mode.md +39 -0
- package/template/.aioson/docs/ux-ui/site-delivery.md +156 -0
- package/template/.aioson/docs/ux-ui/token-contract.md +57 -0
- package/template/.aioson/genomes/copywriting.md +204 -0
- package/template/.aioson/genomes/copywriting.meta.json +48 -0
- package/template/.aioson/git-guard.json +11 -0
- package/template/.aioson/mcp/servers.md +0 -1
- package/template/.aioson/rules/agent-language-policy.md +93 -0
- package/template/.aioson/rules/aioson-context-boundary.md +63 -0
- package/template/.aioson/rules/canonical-path-contract.md +47 -0
- package/template/.aioson/rules/data-format-convention.md +24 -86
- package/template/.aioson/rules/disk-first-artifacts.md +44 -0
- package/template/.aioson/rules/output-brevity.md +44 -0
- package/template/.aioson/rules/prd-section-ownership.md +49 -0
- package/template/.aioson/rules/security-baseline.md +139 -0
- package/template/.aioson/rules/spec-level-ownership.md +61 -0
- package/template/.aioson/rules/squad-driver-pattern.md +81 -0
- package/template/.aioson/schemas/squad-blueprint.schema.json +24 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +44 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +2 -0
- package/template/.aioson/skills/marketing/references/anti-patterns.md +254 -0
- package/template/.aioson/skills/marketing/references/fascinations.md +192 -0
- package/template/.aioson/skills/marketing/references/five-acts.md +248 -0
- package/template/.aioson/skills/marketing/references/market-intelligence.md +198 -0
- package/template/.aioson/skills/marketing/references/offer-structure.md +203 -0
- package/template/.aioson/skills/marketing/references/one-belief.md +149 -0
- package/template/.aioson/skills/marketing/references/patterns.md +218 -0
- package/template/.aioson/skills/marketing/references/pms-research.md +193 -0
- package/template/.aioson/skills/marketing/vsl-craft.md +385 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/pm.md +30 -0
- package/template/.aioson/skills/process/secure-tdd/SKILL.md +97 -0
- package/template/.aioson/skills/process/secure-tdd/references/nextjs.md +81 -0
- package/template/.aioson/skills/process/secure-tdd/references/node-express.md +91 -0
- package/template/.aioson/skills/process/secure-tdd/references/planned-stacks.md +33 -0
- package/template/.aioson/skills/static/harness-validate/SKILL.md +46 -0
- package/template/.aioson/skills/static/landing-page-deploy.md +192 -0
- package/template/.aioson/skills/static/landing-page-forge.md +730 -0
- package/template/.aioson/skills/static/ui-ux-modern.md +1 -0
- package/template/.aioson/skills/static/web-research-cache.md +3 -0
- package/template/.aioson/tasks/squad-create.md +56 -7
- package/template/.aioson/tasks/squad-design.md +80 -2
- package/template/.aioson/tasks/squad-investigate.md +14 -1
- package/template/.aioson/templates/squads/digital-marketing-agency/template.json +96 -0
- package/template/.claude/commands/aioson/agent/committer.md +5 -0
- package/template/.claude/commands/aioson/agent/copywriter.md +5 -0
- package/template/.claude/commands/aioson/agent/cypher.md +5 -0
- package/template/.claude/commands/aioson/agent/pair.md +5 -0
- package/template/.claude/commands/aioson/agent/validator.md +5 -0
- package/template/.gemini/commands/aios-analyst.toml +6 -3
- package/template/.gemini/commands/aios-architect.toml +7 -6
- package/template/.gemini/commands/aios-committer.toml +7 -0
- package/template/.gemini/commands/aios-copywriter.toml +7 -0
- package/template/.gemini/commands/aios-cypher.toml +7 -0
- package/template/.gemini/commands/aios-dev.toml +8 -7
- package/template/.gemini/commands/aios-deyvin.toml +6 -5
- package/template/.gemini/commands/aios-discovery-design-doc.toml +6 -3
- package/template/.gemini/commands/aios-genome.toml +7 -0
- package/template/.gemini/commands/aios-neo.toml +5 -3
- package/template/.gemini/commands/aios-orache.toml +7 -0
- package/template/.gemini/commands/aios-orchestrator.toml +8 -7
- package/template/.gemini/commands/aios-pair.toml +6 -5
- package/template/.gemini/commands/aios-pm.toml +8 -7
- package/template/.gemini/commands/aios-product.toml +5 -3
- package/template/.gemini/commands/aios-qa.toml +6 -5
- package/template/.gemini/commands/aios-setup.toml +5 -2
- package/template/.gemini/commands/aios-sheldon.toml +7 -0
- package/template/.gemini/commands/aios-site-forge.toml +7 -0
- package/template/.gemini/commands/aios-squad.toml +7 -0
- package/template/.gemini/commands/aios-tester.toml +6 -5
- package/template/.gemini/commands/aios-ux-ui.toml +8 -7
- package/template/.gemini/commands/aios-validator.toml +7 -0
- package/template/AGENTS.md +12 -1
- package/template/CLAUDE.md +6 -1
- package/template/.aioson/locales/en/agents/analyst.md +0 -244
- package/template/.aioson/locales/en/agents/architect.md +0 -245
- package/template/.aioson/locales/en/agents/dev.md +0 -397
- package/template/.aioson/locales/en/agents/deyvin.md +0 -137
- package/template/.aioson/locales/en/agents/discovery-design-doc.md +0 -27
- package/template/.aioson/locales/en/agents/genome.md +0 -212
- package/template/.aioson/locales/en/agents/neo.md +0 -8
- package/template/.aioson/locales/en/agents/orache.md +0 -6
- package/template/.aioson/locales/en/agents/orchestrator.md +0 -189
- package/template/.aioson/locales/en/agents/pair.md +0 -5
- package/template/.aioson/locales/en/agents/pm.md +0 -84
- package/template/.aioson/locales/en/agents/product.md +0 -378
- package/template/.aioson/locales/en/agents/profiler-enricher.md +0 -5
- package/template/.aioson/locales/en/agents/profiler-forge.md +0 -5
- package/template/.aioson/locales/en/agents/profiler-researcher.md +0 -5
- package/template/.aioson/locales/en/agents/qa.md +0 -270
- package/template/.aioson/locales/en/agents/setup.md +0 -421
- package/template/.aioson/locales/en/agents/sheldon.md +0 -455
- package/template/.aioson/locales/en/agents/squad.md +0 -449
- package/template/.aioson/locales/en/agents/tester.md +0 -6
- package/template/.aioson/locales/en/agents/ux-ui.md +0 -668
- package/template/.aioson/locales/es/agents/analyst.md +0 -225
- package/template/.aioson/locales/es/agents/architect.md +0 -245
- package/template/.aioson/locales/es/agents/dev.md +0 -370
- package/template/.aioson/locales/es/agents/deyvin.md +0 -99
- package/template/.aioson/locales/es/agents/discovery-design-doc.md +0 -21
- package/template/.aioson/locales/es/agents/genome.md +0 -104
- package/template/.aioson/locales/es/agents/neo.md +0 -50
- package/template/.aioson/locales/es/agents/orache.md +0 -105
- package/template/.aioson/locales/es/agents/orchestrator.md +0 -194
- package/template/.aioson/locales/es/agents/pair.md +0 -7
- package/template/.aioson/locales/es/agents/pm.md +0 -90
- package/template/.aioson/locales/es/agents/product.md +0 -372
- package/template/.aioson/locales/es/agents/profiler-enricher.md +0 -7
- package/template/.aioson/locales/es/agents/profiler-forge.md +0 -7
- package/template/.aioson/locales/es/agents/profiler-researcher.md +0 -7
- package/template/.aioson/locales/es/agents/qa.md +0 -198
- package/template/.aioson/locales/es/agents/setup.md +0 -405
- package/template/.aioson/locales/es/agents/sheldon.md +0 -309
- package/template/.aioson/locales/es/agents/squad.md +0 -532
- package/template/.aioson/locales/es/agents/tester.md +0 -9
- package/template/.aioson/locales/es/agents/ux-ui.md +0 -212
- package/template/.aioson/locales/fr/agents/analyst.md +0 -225
- package/template/.aioson/locales/fr/agents/architect.md +0 -245
- package/template/.aioson/locales/fr/agents/dev.md +0 -370
- package/template/.aioson/locales/fr/agents/deyvin.md +0 -99
- package/template/.aioson/locales/fr/agents/discovery-design-doc.md +0 -21
- package/template/.aioson/locales/fr/agents/genome.md +0 -104
- package/template/.aioson/locales/fr/agents/neo.md +0 -50
- package/template/.aioson/locales/fr/agents/orache.md +0 -106
- package/template/.aioson/locales/fr/agents/orchestrator.md +0 -194
- package/template/.aioson/locales/fr/agents/pair.md +0 -7
- package/template/.aioson/locales/fr/agents/pm.md +0 -90
- package/template/.aioson/locales/fr/agents/product.md +0 -372
- package/template/.aioson/locales/fr/agents/profiler-enricher.md +0 -7
- package/template/.aioson/locales/fr/agents/profiler-forge.md +0 -7
- package/template/.aioson/locales/fr/agents/profiler-researcher.md +0 -7
- package/template/.aioson/locales/fr/agents/qa.md +0 -198
- package/template/.aioson/locales/fr/agents/setup.md +0 -405
- package/template/.aioson/locales/fr/agents/sheldon.md +0 -309
- package/template/.aioson/locales/fr/agents/squad.md +0 -532
- package/template/.aioson/locales/fr/agents/tester.md +0 -9
- package/template/.aioson/locales/fr/agents/ux-ui.md +0 -212
- package/template/.aioson/locales/pt-BR/agents/analyst.md +0 -319
- package/template/.aioson/locales/pt-BR/agents/architect.md +0 -284
- package/template/.aioson/locales/pt-BR/agents/dev.md +0 -483
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +0 -184
- package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +0 -198
- package/template/.aioson/locales/pt-BR/agents/genome.md +0 -297
- package/template/.aioson/locales/pt-BR/agents/neo.md +0 -208
- package/template/.aioson/locales/pt-BR/agents/orache.md +0 -137
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +0 -324
- package/template/.aioson/locales/pt-BR/agents/pair.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/pm.md +0 -182
- package/template/.aioson/locales/pt-BR/agents/product.md +0 -466
- package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +0 -5
- package/template/.aioson/locales/pt-BR/agents/qa.md +0 -300
- package/template/.aioson/locales/pt-BR/agents/setup.md +0 -533
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +0 -323
- package/template/.aioson/locales/pt-BR/agents/squad.md +0 -1330
- package/template/.aioson/locales/pt-BR/agents/tester.md +0 -449
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +0 -669
- package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
|
@@ -9,6 +9,7 @@ const SQUADS_DIR = '.aioson/squads';
|
|
|
9
9
|
|
|
10
10
|
const VALID_TYPES = ['agent', 'assistant', 'clone', 'worker'];
|
|
11
11
|
const VALID_TIERS = ['0', '1', '2', '3'];
|
|
12
|
+
const VALID_MODEL_TIERS = ['powerful', 'balanced', 'fast', 'none'];
|
|
12
13
|
const VALID_DISC = [
|
|
13
14
|
'dominant-driver', 'influential-expressive', 'steady-amiable',
|
|
14
15
|
'compliant-analytical', 'dominant-influential', 'influential-steady',
|
|
@@ -26,6 +27,11 @@ function slugify(name) {
|
|
|
26
27
|
.replace(/^-|-$/g, '');
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
function resolveExecutorModelTier(type, modelTier) {
|
|
31
|
+
if (type === 'worker') return 'none';
|
|
32
|
+
return modelTier || 'balanced';
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
// ---------------------------------------------------------------------------
|
|
30
36
|
// Agent template builder — inspired by AIOX create-agent v3.0 but adapted
|
|
31
37
|
// for aioson's markdown-agent ecosystem (Claude Code, Codex, Gemini CLI).
|
|
@@ -49,8 +55,10 @@ function buildAgentTemplate(slug, opts) {
|
|
|
49
55
|
type = 'agent',
|
|
50
56
|
tier = null,
|
|
51
57
|
disc = null,
|
|
58
|
+
modelTier = null,
|
|
52
59
|
domain = null,
|
|
53
60
|
specialist = null,
|
|
61
|
+
localeScope = 'universal',
|
|
54
62
|
withInfra = false
|
|
55
63
|
} = opts;
|
|
56
64
|
|
|
@@ -61,8 +69,8 @@ function buildAgentTemplate(slug, opts) {
|
|
|
61
69
|
lines.push('');
|
|
62
70
|
|
|
63
71
|
const identity = scope === 'squad' && squadSlug
|
|
64
|
-
? `<!-- identity: squad:${squadSlug}/${slug} | type: ${type}${tier ? ` | tier: ${tier}` : ''} -->`
|
|
65
|
-
: `<!-- identity: my-agent:${slug} | type: ${type}${tier ? ` | tier: ${tier}` : ''} -->`;
|
|
72
|
+
? `<!-- identity: squad:${squadSlug}/${slug} | type: ${type}${tier ? ` | tier: ${tier}` : ''}${modelTier ? ` | modelTier: ${modelTier}` : ''} -->`
|
|
73
|
+
: `<!-- identity: my-agent:${slug} | type: ${type}${tier ? ` | tier: ${tier}` : ''}${modelTier ? ` | modelTier: ${modelTier}` : ''} -->`;
|
|
66
74
|
lines.push(identity);
|
|
67
75
|
lines.push('');
|
|
68
76
|
lines.push(`> ⚡ **ACTIVATED** — Execute immediately as @${slug}.`);
|
|
@@ -88,6 +96,7 @@ function buildAgentTemplate(slug, opts) {
|
|
|
88
96
|
if (scope === 'squad' && squadSlug) {
|
|
89
97
|
lines.push('## Quick context');
|
|
90
98
|
lines.push(`Squad: ${squadName || squadSlug} | Agent: @${slug} | Type: ${type}${tier ? ` | Tier: ${tier}` : ''}`);
|
|
99
|
+
lines.push(`Locale scope: ${localeScope}`);
|
|
91
100
|
if (domain) lines.push(`Domain: ${domain}`);
|
|
92
101
|
lines.push('');
|
|
93
102
|
}
|
|
@@ -215,7 +224,11 @@ function buildAgentTemplate(slug, opts) {
|
|
|
215
224
|
|
|
216
225
|
// ── Hard constraints ────────────────────────────────────────────────────
|
|
217
226
|
lines.push('## Hard constraints');
|
|
218
|
-
|
|
227
|
+
if (scope === 'squad' && localeScope && localeScope !== 'universal') {
|
|
228
|
+
lines.push(`- This squad is locale-specific (${localeScope}). Use that locale for prompt examples and user-facing output inside this squad.`);
|
|
229
|
+
} else {
|
|
230
|
+
lines.push('- Use `interaction_language` from project context for all interaction. If it is absent, fall back to `conversation_language`.');
|
|
231
|
+
}
|
|
219
232
|
lines.push('- Do not invent facts or requirements — ask when uncertain');
|
|
220
233
|
if (scope === 'squad' && squadSlug) {
|
|
221
234
|
lines.push(`- Stay within squad scope: ${squadSlug}`);
|
|
@@ -463,6 +476,8 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
463
476
|
const type = options.type || 'agent';
|
|
464
477
|
const tier = options.tier || null;
|
|
465
478
|
const disc = options.disc || null;
|
|
479
|
+
const modelTier = options['model-tier'] || options.modelTier || null;
|
|
480
|
+
const behavioralProfile = options['behavioral-profile'] || options.behavioralProfile || disc || null;
|
|
466
481
|
const domain = options.domain || null;
|
|
467
482
|
const specialist = options.specialist || null;
|
|
468
483
|
const withInfra = !!options['with-infra'];
|
|
@@ -498,6 +513,18 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
498
513
|
return { ok: false, error: 'invalid_disc' };
|
|
499
514
|
}
|
|
500
515
|
|
|
516
|
+
if (behavioralProfile && !VALID_DISC.includes(behavioralProfile)) {
|
|
517
|
+
const msg = `Invalid behavioral profile: "${behavioralProfile}". Valid: ${VALID_DISC.join(', ')}`;
|
|
518
|
+
logger.error(msg);
|
|
519
|
+
return { ok: false, error: 'invalid_behavioral_profile' };
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (modelTier && !VALID_MODEL_TIERS.includes(modelTier)) {
|
|
523
|
+
const msg = `Invalid model tier: "${modelTier}". Use: ${VALID_MODEL_TIERS.join(', ')}`;
|
|
524
|
+
logger.error(msg);
|
|
525
|
+
return { ok: false, error: 'invalid_model_tier' };
|
|
526
|
+
}
|
|
527
|
+
|
|
501
528
|
// Determine scope
|
|
502
529
|
let resolvedScope = scope;
|
|
503
530
|
if (!resolvedScope) {
|
|
@@ -512,6 +539,8 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
512
539
|
|
|
513
540
|
// If scope=squad, validate squad exists
|
|
514
541
|
let squadName = null;
|
|
542
|
+
let squadManifest = null;
|
|
543
|
+
let localeScope = 'universal';
|
|
515
544
|
if (resolvedScope === 'squad') {
|
|
516
545
|
if (!squadSlug) {
|
|
517
546
|
const squads = await listSquads(projectDir);
|
|
@@ -536,8 +565,9 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
536
565
|
if (await exists(manifestPath)) {
|
|
537
566
|
try {
|
|
538
567
|
const raw = await fs.readFile(manifestPath, 'utf8');
|
|
539
|
-
|
|
540
|
-
squadName =
|
|
568
|
+
squadManifest = JSON.parse(raw);
|
|
569
|
+
squadName = squadManifest.name || squadSlug;
|
|
570
|
+
localeScope = squadManifest.locale_scope || 'universal';
|
|
541
571
|
} catch { squadName = squadSlug; }
|
|
542
572
|
} else {
|
|
543
573
|
squadName = squadSlug;
|
|
@@ -565,7 +595,8 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
565
595
|
// Build agent template
|
|
566
596
|
const content = buildAgentTemplate(slug, {
|
|
567
597
|
mission, focus, scope: resolvedScope,
|
|
568
|
-
squadSlug, squadName, type, tier, disc, domain, specialist,
|
|
598
|
+
squadSlug, squadName, type, tier, disc, modelTier: resolveExecutorModelTier(type, modelTier), domain, specialist,
|
|
599
|
+
localeScope,
|
|
569
600
|
withInfra
|
|
570
601
|
});
|
|
571
602
|
|
|
@@ -574,6 +605,7 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
574
605
|
logger.log(`[dry-run] Would create: ${agentRelPath}`);
|
|
575
606
|
logger.log(`[dry-run] Scope: ${resolvedScope} | Type: ${type}${tier ? ` | Tier: ${tier}` : ''}`);
|
|
576
607
|
if (resolvedScope === 'squad') logger.log(`[dry-run] Squad: ${squadSlug}`);
|
|
608
|
+
if (resolvedScope === 'squad') logger.log(`[dry-run] Locale scope: ${localeScope}`);
|
|
577
609
|
if (withInfra) logger.log('[dry-run] Would generate operational infrastructure stubs');
|
|
578
610
|
logger.log('');
|
|
579
611
|
logger.log(content);
|
|
@@ -623,17 +655,23 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
623
655
|
const manifestPath = path.join(projectDir, SQUADS_DIR, squadSlug, 'squad.manifest.json');
|
|
624
656
|
if (await exists(manifestPath)) {
|
|
625
657
|
try {
|
|
626
|
-
const
|
|
627
|
-
const manifest = JSON.parse(raw);
|
|
658
|
+
const manifest = squadManifest || JSON.parse(await fs.readFile(manifestPath, 'utf8'));
|
|
628
659
|
if (!Array.isArray(manifest.executors)) manifest.executors = [];
|
|
629
660
|
|
|
630
661
|
const alreadyExists = manifest.executors.some(e => e.slug === slug);
|
|
631
662
|
if (!alreadyExists) {
|
|
663
|
+
const resolvedModelTier = resolveExecutorModelTier(type, modelTier);
|
|
632
664
|
manifest.executors.push({
|
|
633
665
|
slug,
|
|
666
|
+
title: name,
|
|
634
667
|
type,
|
|
635
|
-
role: slug,
|
|
668
|
+
role: mission || slug,
|
|
636
669
|
file: agentRelPath,
|
|
670
|
+
usesLLM: type !== 'worker',
|
|
671
|
+
deterministic: type === 'worker',
|
|
672
|
+
modelTier: resolvedModelTier,
|
|
673
|
+
behavioralProfile: behavioralProfile || undefined,
|
|
674
|
+
domain: domain || undefined,
|
|
637
675
|
tier: tier ? Number(tier) : undefined,
|
|
638
676
|
disc: disc || undefined,
|
|
639
677
|
skills: [],
|
|
@@ -651,6 +689,8 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
651
689
|
logger.log(` Agent created: ${agentRelPath}`);
|
|
652
690
|
logger.log(` Scope: ${resolvedScope === 'my-agents' ? 'my-agents (versioned, available globally)' : `squad:${squadSlug}`}`);
|
|
653
691
|
logger.log(` Type: ${type}${tier ? ` | Tier: ${tier}` : ''}${disc ? ` | DISC: ${disc}` : ''}`);
|
|
692
|
+
if (resolvedScope === 'squad') logger.log(` Locale scope: ${localeScope}`);
|
|
693
|
+
if (modelTier || type === 'worker') logger.log(` Model tier: ${resolveExecutorModelTier(type, modelTier)}`);
|
|
654
694
|
logger.log(` Slug: @${slug}`);
|
|
655
695
|
if (registeredClaude) logger.log(' Registered in CLAUDE.md');
|
|
656
696
|
if (registeredAgents) logger.log(' Registered in AGENTS.md');
|
|
@@ -687,6 +727,8 @@ async function runSquadAgentCreate({ args = [], options = {}, logger = console,
|
|
|
687
727
|
type,
|
|
688
728
|
tier: tier ? Number(tier) : null,
|
|
689
729
|
disc,
|
|
730
|
+
modelTier: resolveExecutorModelTier(type, modelTier),
|
|
731
|
+
behavioralProfile,
|
|
690
732
|
squad: squadSlug,
|
|
691
733
|
registeredClaude,
|
|
692
734
|
registeredAgents,
|
|
@@ -22,6 +22,46 @@ async function pathExists(targetPath) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
async function readJsonIfExists(filePath) {
|
|
26
|
+
try {
|
|
27
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
28
|
+
return JSON.parse(raw);
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function writeJson(filePath, value) {
|
|
35
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
36
|
+
await fs.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function syncInvestigationLinkToSquad(projectDir, squadSlug, row) {
|
|
40
|
+
const manifestPath = path.join(projectDir, '.aioson', 'squads', squadSlug, 'squad.manifest.json');
|
|
41
|
+
const blueprintPath = path.join(projectDir, '.aioson', 'squads', '.designs', `${squadSlug}.blueprint.json`);
|
|
42
|
+
const investigationRef = {
|
|
43
|
+
slug: row.investigation_slug,
|
|
44
|
+
path: row.report_path || null,
|
|
45
|
+
confidence: Number(row.confidence) || 0,
|
|
46
|
+
dimensionsCovered: Number(row.dimensions_covered) || 0,
|
|
47
|
+
date: row.created_at ? String(row.created_at).slice(0, 10) : null
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const manifest = await readJsonIfExists(manifestPath);
|
|
51
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
52
|
+
throw new Error(`Squad manifest not found: ${manifestPath}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
manifest.investigation = investigationRef;
|
|
56
|
+
await writeJson(manifestPath, manifest);
|
|
57
|
+
|
|
58
|
+
const blueprint = await readJsonIfExists(blueprintPath);
|
|
59
|
+
if (blueprint && typeof blueprint === 'object') {
|
|
60
|
+
blueprint.investigation = investigationRef;
|
|
61
|
+
await writeJson(blueprintPath, blueprint);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
25
65
|
/**
|
|
26
66
|
* Count how many of the 7 investigation dimensions are present in a report.
|
|
27
67
|
* Looks for headers like "## D1:", "## D2:", ..., "## D7:" in the markdown.
|
|
@@ -164,8 +204,15 @@ async function handleLink(projectDir, invSlug, squadSlug, { logger, t }) {
|
|
|
164
204
|
}
|
|
165
205
|
const { db } = handle;
|
|
166
206
|
try {
|
|
207
|
+
const investigation = getInvestigation(db, invSlug);
|
|
208
|
+
if (!investigation) {
|
|
209
|
+
logger.error(t('squad_investigate.not_found', { slug: invSlug }));
|
|
210
|
+
return { linked: false };
|
|
211
|
+
}
|
|
212
|
+
|
|
167
213
|
const success = linkInvestigation(db, invSlug, squadSlug);
|
|
168
214
|
if (success) {
|
|
215
|
+
await syncInvestigationLinkToSquad(projectDir, squadSlug, investigation);
|
|
169
216
|
logger.log(t('squad_investigate.linked', { investigation: invSlug, squad: squadSlug }));
|
|
170
217
|
} else {
|
|
171
218
|
logger.error(t('squad_investigate.not_found', { slug: invSlug }));
|
|
@@ -206,6 +253,12 @@ async function handleRegister(projectDir, reportPath, options, { logger, t }) {
|
|
|
206
253
|
reportPath: relPath,
|
|
207
254
|
linkedSquadSlug: options.squad || null
|
|
208
255
|
});
|
|
256
|
+
if (options.squad) {
|
|
257
|
+
const row = getInvestigation(db, slug);
|
|
258
|
+
if (row) {
|
|
259
|
+
await syncInvestigationLinkToSquad(projectDir, options.squad, row);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
209
262
|
logger.log(t('squad_investigate.registered', { slug, path: relPath }));
|
|
210
263
|
return { registered: true, slug };
|
|
211
264
|
} finally {
|
|
@@ -26,6 +26,23 @@ async function pathExists(targetPath) {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
async function readManifestInvestigationMeta(projectDir, squadSlug) {
|
|
30
|
+
const manifestPath = path.resolve(projectDir, SQUADS_DIR, squadSlug, 'squad.manifest.json');
|
|
31
|
+
try {
|
|
32
|
+
const raw = await fs.readFile(manifestPath, 'utf8');
|
|
33
|
+
const manifest = JSON.parse(raw);
|
|
34
|
+
const investigation = manifest && typeof manifest.investigation === 'object'
|
|
35
|
+
? manifest.investigation
|
|
36
|
+
: null;
|
|
37
|
+
return {
|
|
38
|
+
slug: investigation?.slug || null,
|
|
39
|
+
path: investigation?.path || null
|
|
40
|
+
};
|
|
41
|
+
} catch {
|
|
42
|
+
return { slug: null, path: null };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
29
46
|
/**
|
|
30
47
|
* Compute hash of squad manifest for staleness detection.
|
|
31
48
|
*/
|
|
@@ -203,6 +220,7 @@ async function handleStale(projectDir, squadSlug, { logger, t }) {
|
|
|
203
220
|
const planDate = new Date(meta.created);
|
|
204
221
|
const manifestFile = path.resolve(projectDir, SQUADS_DIR, squadSlug, 'squad.manifest.json');
|
|
205
222
|
let stale = false;
|
|
223
|
+
const investigationMeta = await readManifestInvestigationMeta(projectDir, squadSlug);
|
|
206
224
|
|
|
207
225
|
try {
|
|
208
226
|
const stat = await fs.stat(manifestFile);
|
|
@@ -231,6 +249,19 @@ async function handleStale(projectDir, squadSlug, { logger, t }) {
|
|
|
231
249
|
// designs dir may not exist
|
|
232
250
|
}
|
|
233
251
|
|
|
252
|
+
if (investigationMeta.path) {
|
|
253
|
+
try {
|
|
254
|
+
const invFile = path.resolve(projectDir, investigationMeta.path);
|
|
255
|
+
const stat = await fs.stat(invFile);
|
|
256
|
+
if (stat.mtime > planDate) {
|
|
257
|
+
logger.log(' ⚠ investigation report modified after plan was created');
|
|
258
|
+
stale = true;
|
|
259
|
+
}
|
|
260
|
+
} catch {
|
|
261
|
+
// linked investigation may be missing on disk
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
234
265
|
if (stale) {
|
|
235
266
|
logger.log(t('squad_plan.is_stale'));
|
|
236
267
|
} else {
|
|
@@ -260,6 +291,7 @@ async function handleRegister(projectDir, squadSlug, { logger, t }) {
|
|
|
260
291
|
const meta = parsePlanFrontmatter(content);
|
|
261
292
|
const rounds = countRounds(content);
|
|
262
293
|
const hash = await computeManifestHash(projectDir, squadSlug);
|
|
294
|
+
const investigationMeta = await readManifestInvestigationMeta(projectDir, squadSlug);
|
|
263
295
|
|
|
264
296
|
const handle = await openRuntimeDb(projectDir);
|
|
265
297
|
const { db } = handle;
|
|
@@ -270,7 +302,7 @@ async function handleRegister(projectDir, squadSlug, { logger, t }) {
|
|
|
270
302
|
roundsTotal: rounds,
|
|
271
303
|
roundsCompleted: 0,
|
|
272
304
|
basedOnBlueprint: meta.based_on_blueprint || null,
|
|
273
|
-
basedOnInvestigation: meta.based_on_investigation || null,
|
|
305
|
+
basedOnInvestigation: meta.based_on_investigation || investigationMeta.slug || investigationMeta.path || null,
|
|
274
306
|
sourceHash: hash
|
|
275
307
|
});
|
|
276
308
|
logger.log(t('squad_plan.registered', { planSlug, rounds }));
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
7
|
* aioson squad:scaffold . --slug=content-team --name="Content Team" --mode=content
|
|
8
|
-
* aioson squad:scaffold . --slug=dev-core --name="Dev Core" --mode=
|
|
9
|
-
* aioson squad:scaffold . --slug=research --name="Research Hub" --mode=
|
|
8
|
+
* aioson squad:scaffold . --slug=dev-core --name="Dev Core" --mode=software
|
|
9
|
+
* aioson squad:scaffold . --slug=research --name="Research Hub" --mode=research
|
|
10
|
+
* aioson squad:scaffold . --slug=studio --name="Studio" --mode=mixed
|
|
10
11
|
* aioson squad:scaffold . --slug=test --json
|
|
11
12
|
*/
|
|
12
13
|
|
|
@@ -17,7 +18,7 @@ async function runSquadScaffold({ args, options = {}, logger }) {
|
|
|
17
18
|
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
18
19
|
const slug = String(options.slug || '').trim();
|
|
19
20
|
const name = String(options.name || slug || '').trim();
|
|
20
|
-
const mode = String(options.mode || '
|
|
21
|
+
const mode = String(options.mode || 'mixed').trim();
|
|
21
22
|
|
|
22
23
|
if (!slug) {
|
|
23
24
|
logger.error('Error: --slug is required');
|
|
@@ -10,6 +10,55 @@ async function readJsonIfExists(filePath) {
|
|
|
10
10
|
} catch { return null; }
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
async function resolveInvestigationEvidence(projectDir, slug, manifest) {
|
|
14
|
+
const investigation = manifest && typeof manifest.investigation === 'object'
|
|
15
|
+
? manifest.investigation
|
|
16
|
+
: null;
|
|
17
|
+
|
|
18
|
+
if (investigation && (investigation.slug || investigation.path)) {
|
|
19
|
+
const relPath = investigation.path
|
|
20
|
+
? String(investigation.path).replace(/\\/g, '/').replace(/^\.\//, '')
|
|
21
|
+
: null;
|
|
22
|
+
let existsOnDisk = false;
|
|
23
|
+
if (relPath) {
|
|
24
|
+
try {
|
|
25
|
+
await fs.access(path.resolve(projectDir, relPath));
|
|
26
|
+
existsOnDisk = true;
|
|
27
|
+
} catch {
|
|
28
|
+
existsOnDisk = false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
present: true,
|
|
34
|
+
source: 'manifest',
|
|
35
|
+
slug: investigation.slug || slug,
|
|
36
|
+
path: relPath,
|
|
37
|
+
existsOnDisk
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const legacyDir = path.join(projectDir, 'squad-searches', slug);
|
|
42
|
+
try {
|
|
43
|
+
await fs.access(legacyDir);
|
|
44
|
+
return {
|
|
45
|
+
present: true,
|
|
46
|
+
source: 'legacy-dir',
|
|
47
|
+
slug,
|
|
48
|
+
path: path.relative(projectDir, legacyDir).replace(/\\/g, '/'),
|
|
49
|
+
existsOnDisk: true
|
|
50
|
+
};
|
|
51
|
+
} catch {
|
|
52
|
+
return {
|
|
53
|
+
present: false,
|
|
54
|
+
source: null,
|
|
55
|
+
slug: null,
|
|
56
|
+
path: null,
|
|
57
|
+
existsOnDisk: false
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
13
62
|
function scoreCompletude(manifest) {
|
|
14
63
|
let score = 0;
|
|
15
64
|
const details = {};
|
|
@@ -37,7 +86,10 @@ function scoreCompletude(manifest) {
|
|
|
37
86
|
if (hasWorker) { score += 2; details.workersPresent = true; }
|
|
38
87
|
|
|
39
88
|
// Investigation report (3pts)
|
|
40
|
-
if (manifest.
|
|
89
|
+
if (manifest._hasInvestigation) {
|
|
90
|
+
score += 3;
|
|
91
|
+
details.investigationReport = manifest._investigationSource || true;
|
|
92
|
+
}
|
|
41
93
|
|
|
42
94
|
// Model tiering (2pts)
|
|
43
95
|
const allTiered = executors.length > 0 && executors.every(e => e.modelTier);
|
|
@@ -139,7 +191,10 @@ function scorePotencial(manifest) {
|
|
|
139
191
|
if (hasVeto) { score += 5; details.antiPatternGuards = true; }
|
|
140
192
|
|
|
141
193
|
// Domain vocabulary — investigation (5pts)
|
|
142
|
-
if (manifest.
|
|
194
|
+
if (manifest._hasInvestigation) {
|
|
195
|
+
score += 5;
|
|
196
|
+
details.domainVocabulary = manifest._investigationSource || true;
|
|
197
|
+
}
|
|
143
198
|
|
|
144
199
|
// Structural patterns — content blueprints (5pts)
|
|
145
200
|
const blueprints = Array.isArray(manifest.contentBlueprints) ? manifest.contentBlueprints : [];
|
|
@@ -187,12 +242,10 @@ async function runSquadScore({ args = [], options = {}, logger = console, transl
|
|
|
187
242
|
return { valid: false, error: 'Manifest not found' };
|
|
188
243
|
}
|
|
189
244
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
manifest._investigationPath = squadSearchDir;
|
|
195
|
-
} catch { /* no investigation */ }
|
|
245
|
+
const investigationEvidence = await resolveInvestigationEvidence(projectDir, slug, manifest);
|
|
246
|
+
manifest._hasInvestigation = investigationEvidence.present;
|
|
247
|
+
manifest._investigationSource = investigationEvidence.source;
|
|
248
|
+
manifest._investigationPath = investigationEvidence.path;
|
|
196
249
|
|
|
197
250
|
const d1 = scoreCompletude(manifest);
|
|
198
251
|
const d2 = scoreProfundidade(manifest);
|
|
@@ -229,12 +282,16 @@ async function runSquadScore({ args = [], options = {}, logger = console, transl
|
|
|
229
282
|
try {
|
|
230
283
|
const { openRuntimeDb } = require('../runtime-store');
|
|
231
284
|
const { db } = openRuntimeDb(projectDir);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
285
|
+
try {
|
|
286
|
+
const now = new Date().toISOString();
|
|
287
|
+
const stmt = db.prepare('INSERT OR REPLACE INTO squad_scores (squad_slug, dimension, score, max_score, details_json, scored_at) VALUES (?, ?, ?, ?, ?, ?)');
|
|
288
|
+
stmt.run(slug, 'completude', d1.score, d1.max, JSON.stringify(d1.details), now);
|
|
289
|
+
stmt.run(slug, 'profundidade', d2.score, d2.max, JSON.stringify(d2.details), now);
|
|
290
|
+
stmt.run(slug, 'qualidade', d3.score, d3.max, JSON.stringify(d3.details), now);
|
|
291
|
+
stmt.run(slug, 'potencial', d4.score, d4.max, JSON.stringify(d4.details), now);
|
|
292
|
+
} finally {
|
|
293
|
+
db.close();
|
|
294
|
+
}
|
|
238
295
|
} catch { /* runtime not available */ }
|
|
239
296
|
|
|
240
297
|
return {
|
|
@@ -239,6 +239,9 @@ async function buildSquadRecordFromPackageDir(targetDir, slug) {
|
|
|
239
239
|
const summaryContent = await fs.readFile(summaryPath, 'utf8').catch(() => null);
|
|
240
240
|
const rules = manifest.rules && typeof manifest.rules === 'object' ? manifest.rules : {};
|
|
241
241
|
const packageInfo = manifest.package && typeof manifest.package === 'object' ? manifest.package : {};
|
|
242
|
+
const investigation = manifest.investigation && typeof manifest.investigation === 'object'
|
|
243
|
+
? manifest.investigation
|
|
244
|
+
: null;
|
|
242
245
|
const agentsDir = normalizeRel(packageInfo.agentsDir || path.join(SQUADS_DIR, slug, 'agents'));
|
|
243
246
|
const outputDir = normalizeRel(rules.outputsDir || `${OUTPUT_ROOT}/${slug}`);
|
|
244
247
|
const logsDir = normalizeRel(rules.logsDir || `${normalizeRel(LOGS_ROOT)}/${slug}`);
|
|
@@ -308,7 +311,13 @@ async function buildSquadRecordFromPackageDir(targetDir, slug) {
|
|
|
308
311
|
: '—',
|
|
309
312
|
mtime: latestHtml?.mtime || manifestStat?.mtime || null,
|
|
310
313
|
tierSummary: buildTierSummary(manifest.executors),
|
|
311
|
-
estimatedCost: estimateRunCost(manifest.executors)
|
|
314
|
+
estimatedCost: estimateRunCost(manifest.executors),
|
|
315
|
+
localeScope: String(manifest.locale_scope || 'universal'),
|
|
316
|
+
localeRationale: manifest.locale_rationale || null,
|
|
317
|
+
domainTier: manifest.domainClassification?.tier || null,
|
|
318
|
+
investigationSlug: investigation?.slug || null,
|
|
319
|
+
investigationPath: investigation?.path ? normalizeRel(investigation.path) : null,
|
|
320
|
+
sourceDocsCount: Array.isArray(manifest.sourceDocs) ? manifest.sourceDocs.length : 0
|
|
312
321
|
};
|
|
313
322
|
}
|
|
314
323
|
|
|
@@ -446,6 +455,18 @@ async function runSquadStatus({ args, logger, t }) {
|
|
|
446
455
|
if (squad.estimatedCost != null) {
|
|
447
456
|
logger.log(t('squad_status.estimated_cost', { value: squad.estimatedCost.toFixed(3) }));
|
|
448
457
|
}
|
|
458
|
+
if (squad.localeScope) {
|
|
459
|
+
logger.log(` Locale scope: ${squad.localeScope}${squad.localeRationale ? ` — ${squad.localeRationale}` : ''}`);
|
|
460
|
+
}
|
|
461
|
+
if (squad.domainTier) {
|
|
462
|
+
logger.log(` Domain tier: ${squad.domainTier}`);
|
|
463
|
+
}
|
|
464
|
+
if (squad.investigationSlug) {
|
|
465
|
+
logger.log(` Investigation: ${squad.investigationSlug}${squad.investigationPath ? ` → ${squad.investigationPath}` : ''}`);
|
|
466
|
+
}
|
|
467
|
+
if (squad.sourceDocsCount > 0) {
|
|
468
|
+
logger.log(` Source docs: ${squad.sourceDocsCount}`);
|
|
469
|
+
}
|
|
449
470
|
if (i < squads.length - 1) logger.log('');
|
|
450
471
|
}
|
|
451
472
|
|
|
@@ -14,6 +14,14 @@ async function readJsonIfExists(filePath) {
|
|
|
14
14
|
} catch { return null; }
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
function normalizeRelPath(relPath) {
|
|
18
|
+
return String(relPath || '').replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isLocaleSpecific(localeScope) {
|
|
22
|
+
return Boolean(localeScope && localeScope !== 'universal');
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
function validateManifestFields(manifest) {
|
|
18
26
|
const errors = [];
|
|
19
27
|
const warnings = [];
|
|
@@ -33,6 +41,18 @@ function validateManifestFields(manifest) {
|
|
|
33
41
|
warnings.push(`Unknown mode: "${manifest.mode}"`);
|
|
34
42
|
}
|
|
35
43
|
|
|
44
|
+
if (manifest.locale_scope && !/^(universal|[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*)$/.test(manifest.locale_scope)) {
|
|
45
|
+
errors.push(`Invalid locale_scope: "${manifest.locale_scope}"`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!manifest.package || typeof manifest.package !== 'object') {
|
|
49
|
+
warnings.push('Missing package object — squad uses legacy manifest contract');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!manifest.rules || typeof manifest.rules !== 'object') {
|
|
53
|
+
warnings.push('Missing rules object — squad uses legacy manifest contract');
|
|
54
|
+
}
|
|
55
|
+
|
|
36
56
|
return { errors, warnings };
|
|
37
57
|
}
|
|
38
58
|
|
|
@@ -77,9 +97,10 @@ async function validateStructure(projectDir, slug, manifest) {
|
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
// Check output dir (warning only)
|
|
80
|
-
const
|
|
100
|
+
const outputRel = normalizeRelPath(manifest?.rules?.outputsDir || `output/${slug}`);
|
|
101
|
+
const outputDir = path.join(projectDir, outputRel);
|
|
81
102
|
if (!(await pathExists(outputDir))) {
|
|
82
|
-
warnings.push(`Output directory not found:
|
|
103
|
+
warnings.push(`Output directory not found: ${outputRel}/`);
|
|
83
104
|
}
|
|
84
105
|
|
|
85
106
|
return { errors, warnings };
|
|
@@ -267,6 +288,76 @@ async function validateSemanticDeep(projectDir, slug, manifest) {
|
|
|
267
288
|
}
|
|
268
289
|
}
|
|
269
290
|
|
|
291
|
+
// 8. Canonical package contract
|
|
292
|
+
const packageInfo = manifest.package && typeof manifest.package === 'object' ? manifest.package : {};
|
|
293
|
+
const rules = manifest.rules && typeof manifest.rules === 'object' ? manifest.rules : {};
|
|
294
|
+
const canonicalPaths = [
|
|
295
|
+
['package.rootDir', packageInfo.rootDir, `.aioson/squads/${slug}`],
|
|
296
|
+
['package.agentsDir', packageInfo.agentsDir, `.aioson/squads/${slug}/agents`],
|
|
297
|
+
['package.workersDir', packageInfo.workersDir, `.aioson/squads/${slug}/workers`],
|
|
298
|
+
['package.workflowsDir', packageInfo.workflowsDir, `.aioson/squads/${slug}/workflows`],
|
|
299
|
+
['package.checklistsDir', packageInfo.checklistsDir, `.aioson/squads/${slug}/checklists`],
|
|
300
|
+
['package.skillsDir', packageInfo.skillsDir, `.aioson/squads/${slug}/skills`],
|
|
301
|
+
['package.templatesDir', packageInfo.templatesDir, `.aioson/squads/${slug}/templates`],
|
|
302
|
+
['package.docsDir', packageInfo.docsDir, `.aioson/squads/${slug}/docs`],
|
|
303
|
+
['rules.outputsDir', rules.outputsDir, `output/${slug}`],
|
|
304
|
+
['rules.logsDir', rules.logsDir, `aioson-logs/${slug}`],
|
|
305
|
+
['rules.mediaDir', rules.mediaDir, `media/${slug}`]
|
|
306
|
+
];
|
|
307
|
+
|
|
308
|
+
for (const [label, actual, expected] of canonicalPaths) {
|
|
309
|
+
if (!actual) {
|
|
310
|
+
warnings.push(`Missing ${label} — expected "${expected}"`);
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
if (normalizeRelPath(actual) !== expected) {
|
|
314
|
+
warnings.push(`${label} points to "${actual}" instead of canonical "${expected}"`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 9. Locale policy validation
|
|
319
|
+
if (isLocaleSpecific(manifest.locale_scope) && !manifest.locale_rationale) {
|
|
320
|
+
warnings.push(`locale_scope "${manifest.locale_scope}" is locale-specific but locale_rationale is missing`);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// 10. Source docs validation
|
|
324
|
+
const sourceDocs = Array.isArray(manifest.sourceDocs) ? manifest.sourceDocs : [];
|
|
325
|
+
for (const docPath of sourceDocs) {
|
|
326
|
+
const absPath = path.join(projectDir, normalizeRelPath(docPath));
|
|
327
|
+
if (!(await pathExists(absPath))) {
|
|
328
|
+
warnings.push(`sourceDocs entry not found: ${docPath}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// 11. Investigation validation
|
|
333
|
+
const investigation = manifest.investigation && typeof manifest.investigation === 'object'
|
|
334
|
+
? manifest.investigation
|
|
335
|
+
: null;
|
|
336
|
+
const domainClassification = manifest.domainClassification && typeof manifest.domainClassification === 'object'
|
|
337
|
+
? manifest.domainClassification
|
|
338
|
+
: null;
|
|
339
|
+
|
|
340
|
+
if (investigation) {
|
|
341
|
+
if (!investigation.slug) {
|
|
342
|
+
warnings.push('investigation object is missing "slug"');
|
|
343
|
+
}
|
|
344
|
+
if (investigation.path) {
|
|
345
|
+
const investigationPath = path.join(projectDir, normalizeRelPath(investigation.path));
|
|
346
|
+
if (!(await pathExists(investigationPath))) {
|
|
347
|
+
warnings.push(`investigation.path not found: ${investigation.path}`);
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
warnings.push('investigation object is missing "path"');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const investigationRequired = domainClassification?.tier === 'tier-1-regulated'
|
|
355
|
+
|| domainClassification?.investigationPolicy === 'required';
|
|
356
|
+
|
|
357
|
+
if (investigationRequired && !manifest.ephemeral && !investigation) {
|
|
358
|
+
errors.push('Regulated squad is missing required investigation metadata');
|
|
359
|
+
}
|
|
360
|
+
|
|
270
361
|
return { errors, warnings };
|
|
271
362
|
}
|
|
272
363
|
|