@jaimevalasek/aioson 1.7.2 → 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 +35 -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 +42 -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/cypher.md +252 -0
- package/template/.aioson/agents/dev.md +112 -628
- package/template/.aioson/agents/deyvin.md +33 -236
- 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 +5 -7
- 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 +168 -514
- package/template/.aioson/agents/setup.md +52 -278
- package/template/.aioson/agents/sheldon.md +122 -754
- package/template/.aioson/agents/site-forge.md +111 -1583
- package/template/.aioson/agents/squad.md +139 -2010
- package/template/.aioson/agents/tester.md +10 -0
- package/template/.aioson/agents/ux-ui.md +104 -812
- 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.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/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/web-research-cache.md +3 -0
- package/template/.aioson/tasks/squad-create.md +35 -8
- package/template/.aioson/tasks/squad-design.md +50 -2
- package/template/.aioson/tasks/squad-investigate.md +14 -1
- 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 +5 -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
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { exists } = require('../utils');
|
|
6
|
+
const { readConfig } = require('./config');
|
|
7
|
+
|
|
8
|
+
const WORKSPACE_FILE = '.aioson/workspace.json';
|
|
9
|
+
const DEFAULT_BASE_URL = 'https://aioson.com';
|
|
10
|
+
|
|
11
|
+
function slugify(text) {
|
|
12
|
+
return String(text || '')
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
15
|
+
.replace(/^-+|-+$/g, '')
|
|
16
|
+
.slice(0, 60);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function findProjectRoot(startDir) {
|
|
20
|
+
let current = path.resolve(startDir || '.');
|
|
21
|
+
for (let i = 0; i < 12; i++) {
|
|
22
|
+
try {
|
|
23
|
+
await fs.access(path.join(current, '.aioson'));
|
|
24
|
+
return current;
|
|
25
|
+
} catch {
|
|
26
|
+
const parent = path.dirname(current);
|
|
27
|
+
if (parent === current) break;
|
|
28
|
+
current = parent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return path.resolve(startDir || '.');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function readWorkspace(projectDir) {
|
|
35
|
+
const wsPath = path.join(projectDir, WORKSPACE_FILE);
|
|
36
|
+
if (!(await exists(wsPath))) return null;
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(await fs.readFile(wsPath, 'utf8'));
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function writeWorkspace(projectDir, data) {
|
|
45
|
+
const wsPath = path.join(projectDir, WORKSPACE_FILE);
|
|
46
|
+
await fs.writeFile(wsPath, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
|
|
47
|
+
return wsPath;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function runWorkspaceInit({ args, options, logger, t }) {
|
|
51
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
52
|
+
const projectDir = await findProjectRoot(targetDir);
|
|
53
|
+
const wsPath = path.join(projectDir, WORKSPACE_FILE);
|
|
54
|
+
|
|
55
|
+
if ((await exists(wsPath)) && !options.force) {
|
|
56
|
+
const ws = JSON.parse(await fs.readFile(wsPath, 'utf8'));
|
|
57
|
+
const config = await readConfig();
|
|
58
|
+
const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
59
|
+
logger.log(t('workspace.already_linked', { slug: ws.slug, url: `${baseUrl}/workspaces/${ws.slug}` }));
|
|
60
|
+
return { ok: true, slug: ws.slug, alreadyExists: true };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const config = await readConfig();
|
|
64
|
+
const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
65
|
+
const username = slugify(config.aiosonUsername || 'local');
|
|
66
|
+
const projectName = slugify(options.name || path.basename(projectDir));
|
|
67
|
+
const baseSlug = `${username}-${projectName}`;
|
|
68
|
+
const token = config.aiosonToken;
|
|
69
|
+
|
|
70
|
+
let workspaceId = `wks_local_${Date.now()}`;
|
|
71
|
+
let finalSlug = baseSlug;
|
|
72
|
+
|
|
73
|
+
if (token) {
|
|
74
|
+
try {
|
|
75
|
+
logger.log(t('workspace.registering'));
|
|
76
|
+
const response = await fetch(`${baseUrl}/api/workspaces`, {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
headers: {
|
|
79
|
+
authorization: `Bearer ${token}`,
|
|
80
|
+
'content-type': 'application/json',
|
|
81
|
+
accept: 'application/json'
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({ slug: baseSlug, projectName }),
|
|
84
|
+
signal: AbortSignal.timeout(10000)
|
|
85
|
+
});
|
|
86
|
+
if (response.ok) {
|
|
87
|
+
const data = await response.json();
|
|
88
|
+
// /api/workspaces POST returns { ok, workspace: { id, name, slug } }
|
|
89
|
+
workspaceId = data.workspace?.id || data.workspaceId || workspaceId;
|
|
90
|
+
finalSlug = data.workspace?.slug || data.slug || baseSlug;
|
|
91
|
+
}
|
|
92
|
+
} catch {
|
|
93
|
+
// Offline — use local ID, will sync later
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const wsData = { slug: finalSlug, workspaceId, createdAt: new Date().toISOString() };
|
|
98
|
+
const writtenPath = await writeWorkspace(projectDir, wsData);
|
|
99
|
+
|
|
100
|
+
logger.log(t('workspace.init_ok', { slug: finalSlug, path: writtenPath, url: `${baseUrl}/workspaces/${finalSlug}` }));
|
|
101
|
+
return { ok: true, slug: finalSlug, workspaceId, path: writtenPath };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function runWorkspaceStatus({ args, options, logger, t }) {
|
|
105
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
106
|
+
const projectDir = await findProjectRoot(targetDir);
|
|
107
|
+
const ws = await readWorkspace(projectDir);
|
|
108
|
+
|
|
109
|
+
if (!ws) {
|
|
110
|
+
logger.log(t('workspace.not_linked'));
|
|
111
|
+
logger.log(t('workspace.init_hint'));
|
|
112
|
+
return { ok: true, linked: false };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const config = await readConfig();
|
|
116
|
+
const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
117
|
+
|
|
118
|
+
logger.log(t('workspace.status_slug', { slug: ws.slug }));
|
|
119
|
+
logger.log(t('workspace.status_id', { id: ws.workspaceId }));
|
|
120
|
+
logger.log(t('workspace.status_url', { url: `${baseUrl}/workspaces/${ws.slug}` }));
|
|
121
|
+
logger.log(t('workspace.status_created', { date: ws.createdAt }));
|
|
122
|
+
|
|
123
|
+
return { ok: true, linked: true, ...ws };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function runWorkspaceOpen({ args, options, logger, t }) {
|
|
127
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
128
|
+
const projectDir = await findProjectRoot(targetDir);
|
|
129
|
+
const ws = await readWorkspace(projectDir);
|
|
130
|
+
|
|
131
|
+
if (!ws) {
|
|
132
|
+
logger.log(t('workspace.not_linked'));
|
|
133
|
+
logger.log(t('workspace.init_hint'));
|
|
134
|
+
return { ok: false, error: { code: 'not_linked' } };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const config = await readConfig();
|
|
138
|
+
const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
139
|
+
const url = `${baseUrl}/workspaces/${ws.slug}`;
|
|
140
|
+
logger.log(t('workspace.open_url', { url }));
|
|
141
|
+
return { ok: true, url };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = { runWorkspaceInit, runWorkspaceStatus, runWorkspaceOpen, readWorkspace, findProjectRoot };
|
package/src/constants.js
CHANGED
|
@@ -29,7 +29,9 @@ const MANAGED_FILES = [
|
|
|
29
29
|
'.aioson/agents/pm.md',
|
|
30
30
|
'.aioson/agents/dev.md',
|
|
31
31
|
'.aioson/agents/qa.md',
|
|
32
|
+
'.aioson/agents/tester.md',
|
|
32
33
|
'.aioson/agents/orchestrator.md',
|
|
34
|
+
'.aioson/agents/pentester.md',
|
|
33
35
|
'.aioson/agents/squad.md',
|
|
34
36
|
'.aioson/agents/orache.md',
|
|
35
37
|
'.aioson/agents/genome.md',
|
|
@@ -39,78 +41,28 @@ const MANAGED_FILES = [
|
|
|
39
41
|
'.aioson/agents/profiler-enricher.md',
|
|
40
42
|
'.aioson/agents/profiler-forge.md',
|
|
41
43
|
'.aioson/agents/copywriter.md',
|
|
42
|
-
'.aioson/
|
|
43
|
-
'.aioson/
|
|
44
|
-
'.aioson/
|
|
45
|
-
'.aioson/
|
|
46
|
-
'.aioson/
|
|
47
|
-
'.aioson/
|
|
48
|
-
'.aioson/
|
|
49
|
-
'.aioson/
|
|
50
|
-
'.aioson/
|
|
51
|
-
'.aioson/
|
|
52
|
-
'.aioson/
|
|
53
|
-
'.aioson/
|
|
54
|
-
'.aioson/
|
|
55
|
-
'.aioson/
|
|
56
|
-
'.aioson/
|
|
57
|
-
'.aioson/
|
|
58
|
-
'.aioson/
|
|
59
|
-
'.aioson/
|
|
60
|
-
'.aioson/
|
|
61
|
-
'.aioson/
|
|
62
|
-
'.aioson/
|
|
63
|
-
'.aioson/
|
|
64
|
-
'.aioson/locales/pt-BR/agents/ux-ui.md',
|
|
65
|
-
'.aioson/locales/pt-BR/agents/product.md',
|
|
66
|
-
'.aioson/locales/pt-BR/agents/deyvin.md',
|
|
67
|
-
'.aioson/locales/pt-BR/agents/pair.md',
|
|
68
|
-
'.aioson/locales/pt-BR/agents/pm.md',
|
|
69
|
-
'.aioson/locales/pt-BR/agents/dev.md',
|
|
70
|
-
'.aioson/locales/pt-BR/agents/qa.md',
|
|
71
|
-
'.aioson/locales/pt-BR/agents/orchestrator.md',
|
|
72
|
-
'.aioson/locales/pt-BR/agents/squad.md',
|
|
73
|
-
'.aioson/locales/pt-BR/agents/orache.md',
|
|
74
|
-
'.aioson/locales/pt-BR/agents/genome.md',
|
|
75
|
-
'.aioson/locales/pt-BR/agents/profiler-researcher.md',
|
|
76
|
-
'.aioson/locales/pt-BR/agents/profiler-enricher.md',
|
|
77
|
-
'.aioson/locales/pt-BR/agents/profiler-forge.md',
|
|
78
|
-
'.aioson/locales/es/agents/setup.md',
|
|
79
|
-
'.aioson/locales/es/agents/discovery-design-doc.md',
|
|
80
|
-
'.aioson/locales/es/agents/analyst.md',
|
|
81
|
-
'.aioson/locales/es/agents/architect.md',
|
|
82
|
-
'.aioson/locales/es/agents/ux-ui.md',
|
|
83
|
-
'.aioson/locales/es/agents/product.md',
|
|
84
|
-
'.aioson/locales/es/agents/deyvin.md',
|
|
85
|
-
'.aioson/locales/es/agents/pair.md',
|
|
86
|
-
'.aioson/locales/es/agents/pm.md',
|
|
87
|
-
'.aioson/locales/es/agents/dev.md',
|
|
88
|
-
'.aioson/locales/es/agents/qa.md',
|
|
89
|
-
'.aioson/locales/es/agents/orchestrator.md',
|
|
90
|
-
'.aioson/locales/es/agents/squad.md',
|
|
91
|
-
'.aioson/locales/es/agents/orache.md',
|
|
92
|
-
'.aioson/locales/es/agents/genome.md',
|
|
93
|
-
'.aioson/locales/es/agents/profiler-researcher.md',
|
|
94
|
-
'.aioson/locales/es/agents/profiler-enricher.md',
|
|
95
|
-
'.aioson/locales/es/agents/profiler-forge.md',
|
|
96
|
-
'.aioson/locales/fr/agents/setup.md',
|
|
97
|
-
'.aioson/locales/fr/agents/discovery-design-doc.md',
|
|
98
|
-
'.aioson/locales/fr/agents/analyst.md',
|
|
99
|
-
'.aioson/locales/fr/agents/architect.md',
|
|
100
|
-
'.aioson/locales/fr/agents/ux-ui.md',
|
|
101
|
-
'.aioson/locales/fr/agents/product.md',
|
|
102
|
-
'.aioson/locales/fr/agents/deyvin.md',
|
|
103
|
-
'.aioson/locales/fr/agents/pair.md',
|
|
104
|
-
'.aioson/locales/fr/agents/pm.md',
|
|
105
|
-
'.aioson/locales/fr/agents/dev.md',
|
|
106
|
-
'.aioson/locales/fr/agents/qa.md',
|
|
107
|
-
'.aioson/locales/fr/agents/orchestrator.md',
|
|
108
|
-
'.aioson/locales/fr/agents/squad.md',
|
|
109
|
-
'.aioson/locales/fr/agents/orache.md',
|
|
110
|
-
'.aioson/locales/fr/agents/genome.md',
|
|
111
|
-
'.aioson/locales/fr/agents/profiler-researcher.md',
|
|
112
|
-
'.aioson/locales/fr/agents/profiler-enricher.md',
|
|
113
|
-
'.aioson/locales/fr/agents/profiler-forge.md',
|
|
44
|
+
'.aioson/docs/squad/package-contract.md',
|
|
45
|
+
'.aioson/docs/squad/creation-flow.md',
|
|
46
|
+
'.aioson/docs/squad/research-loop.md',
|
|
47
|
+
'.aioson/docs/squad/quality-lens.md',
|
|
48
|
+
'.aioson/docs/squad/workflow-quality.md',
|
|
49
|
+
'.aioson/docs/squad/content-output.md',
|
|
50
|
+
'.aioson/docs/squad/session-operations.md',
|
|
51
|
+
'.aioson/docs/squad/genome-bindings.md',
|
|
52
|
+
'.aioson/docs/product/conversation-playbook.md',
|
|
53
|
+
'.aioson/docs/product/research-loop.md',
|
|
54
|
+
'.aioson/docs/product/quality-lens.md',
|
|
55
|
+
'.aioson/docs/product/prd-contract.md',
|
|
56
|
+
'.aioson/docs/deyvin/continuity-recovery.md',
|
|
57
|
+
'.aioson/docs/deyvin/pair-execution.md',
|
|
58
|
+
'.aioson/docs/deyvin/runtime-handoffs.md',
|
|
59
|
+
'.aioson/docs/deyvin/debugging-escalation.md',
|
|
60
|
+
'.aioson/docs/sheldon/research-loop.md',
|
|
61
|
+
'.aioson/docs/sheldon/web-intelligence.md',
|
|
62
|
+
'.aioson/docs/sheldon/quality-lens.md',
|
|
63
|
+
'.aioson/docs/sheldon/enrichment-paths.md',
|
|
64
|
+
'.aioson/docs/dev/stack-conventions.md',
|
|
65
|
+
'.aioson/docs/dev/execution-discipline.md',
|
|
114
66
|
'.aioson/skills/static/laravel-conventions.md',
|
|
115
67
|
'.aioson/skills/static/tall-stack-patterns.md',
|
|
116
68
|
'.aioson/skills/static/jetstream-setup.md',
|
|
@@ -217,7 +169,7 @@ const CONTEXT_REQUIRED_FIELDS = [
|
|
|
217
169
|
];
|
|
218
170
|
|
|
219
171
|
const CONTEXT_ALLOWED_CLASSIFICATIONS = ['MICRO', 'SMALL', 'MEDIUM'];
|
|
220
|
-
const CONTEXT_ALLOWED_PROJECT_TYPES = ['web_app', 'api', 'site', 'script', 'dapp'];
|
|
172
|
+
const CONTEXT_ALLOWED_PROJECT_TYPES = ['web_app', 'api', 'site', 'script', 'dapp', 'desktop_app'];
|
|
221
173
|
const CONTEXT_ALLOWED_PROFILES = ['developer', 'beginner', 'team'];
|
|
222
174
|
|
|
223
175
|
const AGENT_DEFINITIONS = [
|
|
@@ -295,7 +247,8 @@ const AGENT_DEFINITIONS = [
|
|
|
295
247
|
'.aioson/context/project.context.md',
|
|
296
248
|
'.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
|
|
297
249
|
'.aioson/context/discovery.md',
|
|
298
|
-
'.aioson/context/architecture.md'
|
|
250
|
+
'.aioson/context/architecture.md',
|
|
251
|
+
'.aioson/context/ui-spec.md (when present)'
|
|
299
252
|
],
|
|
300
253
|
output: '.aioson/context/prd.md or prd-{slug}.md (enriched with delivery plan and acceptance criteria)'
|
|
301
254
|
},
|
|
@@ -311,6 +264,17 @@ const AGENT_DEFINITIONS = [
|
|
|
311
264
|
],
|
|
312
265
|
output: 'code changes'
|
|
313
266
|
},
|
|
267
|
+
{
|
|
268
|
+
id: 'pentester',
|
|
269
|
+
displayName: 'Pentester',
|
|
270
|
+
command: '@pentester',
|
|
271
|
+
path: '.aioson/agents/pentester.md',
|
|
272
|
+
dependsOn: [
|
|
273
|
+
'.aioson/context/project.context.md',
|
|
274
|
+
'.aioson/context/spec-{slug}.md (active feature)'
|
|
275
|
+
],
|
|
276
|
+
output: '.aioson/context/security-findings-{slug}.json'
|
|
277
|
+
},
|
|
314
278
|
{
|
|
315
279
|
id: 'qa',
|
|
316
280
|
displayName: 'QA',
|
|
@@ -333,9 +297,12 @@ const AGENT_DEFINITIONS = [
|
|
|
333
297
|
command: '@orchestrator',
|
|
334
298
|
path: '.aioson/agents/orchestrator.md',
|
|
335
299
|
dependsOn: [
|
|
300
|
+
'.aioson/context/project.context.md',
|
|
336
301
|
'.aioson/context/discovery.md',
|
|
337
302
|
'.aioson/context/architecture.md',
|
|
338
|
-
'.aioson/context/prd.md'
|
|
303
|
+
'.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
|
|
304
|
+
'.aioson/context/ui-spec.md (when present)',
|
|
305
|
+
'.aioson/context/implementation-plan.md or implementation-plan-{slug}.md (when present)'
|
|
339
306
|
],
|
|
340
307
|
output: '.aioson/context/parallel/*.status.md'
|
|
341
308
|
},
|
package/src/context-memory.js
CHANGED
|
@@ -21,6 +21,11 @@ const SCAN_INDEX_FILE = `${CONTEXT_DIR}/scan-index.md`;
|
|
|
21
21
|
const SCAN_FOLDERS_FILE = `${CONTEXT_DIR}/scan-folders.md`;
|
|
22
22
|
const SCAN_AIOSON_FILE = `${CONTEXT_DIR}/scan-aioson.md`;
|
|
23
23
|
const CONTEXT_PACK_FILE = `${CONTEXT_DIR}/context-pack.md`;
|
|
24
|
+
const BOOTSTRAP_DIR = '.aioson/context/bootstrap';
|
|
25
|
+
const BOOTSTRAP_WHAT_IS = `${BOOTSTRAP_DIR}/what-is.md`;
|
|
26
|
+
const BOOTSTRAP_HOW_IT_WORKS = `${BOOTSTRAP_DIR}/how-it-works.md`;
|
|
27
|
+
const BOOTSTRAP_WHAT_IT_DOES = `${BOOTSTRAP_DIR}/what-it-does.md`;
|
|
28
|
+
const BOOTSTRAP_CURRENT_STATE = `${BOOTSTRAP_DIR}/current-state.md`;
|
|
24
29
|
|
|
25
30
|
const SPEC_SECTION_ALIASES = {
|
|
26
31
|
stack: ['stack'],
|
|
@@ -138,6 +143,34 @@ const CONTEXT_DOC_SPECS = [
|
|
|
138
143
|
group: 'scan',
|
|
139
144
|
readWhen: 'you need generated context pages, squads, genomes or local MCP artifacts',
|
|
140
145
|
tags: ['scan', 'brownfield', 'aioson']
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
relPath: BOOTSTRAP_WHAT_IS,
|
|
149
|
+
title: 'System Identity',
|
|
150
|
+
group: 'bootstrap',
|
|
151
|
+
readWhen: 'you need to understand what the system IS, who uses it, and why it exists',
|
|
152
|
+
tags: ['bootstrap', 'identity', 'semantic']
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
relPath: BOOTSTRAP_HOW_IT_WORKS,
|
|
156
|
+
title: 'System Mechanics',
|
|
157
|
+
group: 'bootstrap',
|
|
158
|
+
readWhen: 'you need to understand how the system works — architecture, modules, data flow',
|
|
159
|
+
tags: ['bootstrap', 'architecture', 'semantic']
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
relPath: BOOTSTRAP_WHAT_IT_DOES,
|
|
163
|
+
title: 'System Features',
|
|
164
|
+
group: 'bootstrap',
|
|
165
|
+
readWhen: 'you need to know what features exist, business rules, and user workflows',
|
|
166
|
+
tags: ['bootstrap', 'features', 'semantic']
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
relPath: BOOTSTRAP_CURRENT_STATE,
|
|
170
|
+
title: 'System Current State',
|
|
171
|
+
group: 'bootstrap',
|
|
172
|
+
readWhen: 'you need to know what is implemented, in progress, or planned',
|
|
173
|
+
tags: ['bootstrap', 'state', 'semantic']
|
|
141
174
|
}
|
|
142
175
|
];
|
|
143
176
|
|
|
@@ -499,9 +532,10 @@ function buildMemoryIndexMarkdown({ generatedAt, catalog }) {
|
|
|
499
532
|
''
|
|
500
533
|
];
|
|
501
534
|
|
|
502
|
-
const groupOrder = ['foundation', 'system', 'development', 'scope', 'modules', 'scan'];
|
|
535
|
+
const groupOrder = ['foundation', 'bootstrap', 'system', 'development', 'scope', 'modules', 'scan'];
|
|
503
536
|
const groupTitles = {
|
|
504
537
|
foundation: 'Foundation Docs',
|
|
538
|
+
bootstrap: 'Bootstrap — Semantic Knowledge Cache',
|
|
505
539
|
system: 'System Memory',
|
|
506
540
|
development: 'Development Memory',
|
|
507
541
|
scope: 'Scope Docs',
|
|
@@ -534,6 +568,7 @@ function rankContextDoc(doc, { agent, goal, module }) {
|
|
|
534
568
|
const lowerGoal = normalizeForLookup(goal);
|
|
535
569
|
const lowerAgent = normalizeForLookup(agent);
|
|
536
570
|
const lowerModule = normalizeForLookup(module);
|
|
571
|
+
const lookupText = `${lowerAgent} ${lowerGoal}`.trim();
|
|
537
572
|
|
|
538
573
|
if (doc.relPath === PROJECT_CONTEXT_FILE) {
|
|
539
574
|
score += 100;
|
|
@@ -579,6 +614,24 @@ function rankContextDoc(doc, { agent, goal, module }) {
|
|
|
579
614
|
score += 35;
|
|
580
615
|
reasons.push('readiness signal');
|
|
581
616
|
}
|
|
617
|
+
if (doc.group === 'bootstrap') {
|
|
618
|
+
if (doc.relPath === BOOTSTRAP_WHAT_IS && /(product|analyst|what|identity|understand|discover|bootstrap|memory|continuity)/.test(lookupText)) {
|
|
619
|
+
score += 70;
|
|
620
|
+
reasons.push('semantic system identity');
|
|
621
|
+
}
|
|
622
|
+
if (doc.relPath === BOOTSTRAP_HOW_IT_WORKS && /(dev|architect|how|architecture|implement|refactor|bootstrap|memory|continuity)/.test(lookupText)) {
|
|
623
|
+
score += 70;
|
|
624
|
+
reasons.push('semantic system mechanics');
|
|
625
|
+
}
|
|
626
|
+
if (doc.relPath === BOOTSTRAP_WHAT_IT_DOES && /(product|analyst|feature|business|rule|workflow|bootstrap|memory|continuity)/.test(lookupText)) {
|
|
627
|
+
score += 65;
|
|
628
|
+
reasons.push('semantic features and business rules');
|
|
629
|
+
}
|
|
630
|
+
if (doc.relPath === BOOTSTRAP_CURRENT_STATE && /(dev|qa|state|current|progress|status|bootstrap|memory|continuity)/.test(lookupText)) {
|
|
631
|
+
score += 65;
|
|
632
|
+
reasons.push('semantic current state');
|
|
633
|
+
}
|
|
634
|
+
}
|
|
582
635
|
if (/module-/.test(doc.relPath) && lowerModule) {
|
|
583
636
|
if (normalizeForLookup(doc.relPath).includes(lowerModule)) {
|
|
584
637
|
score += 80;
|
|
@@ -737,6 +790,67 @@ async function writeDerivedContextMemory({
|
|
|
737
790
|
};
|
|
738
791
|
}
|
|
739
792
|
|
|
793
|
+
async function collectActiveDossiers(targetDir) {
|
|
794
|
+
const featuresDir = path.join(targetDir, CONTEXT_DIR, 'features');
|
|
795
|
+
let slugs = [];
|
|
796
|
+
try {
|
|
797
|
+
const entries = await fs.readdir(featuresDir, { withFileTypes: true });
|
|
798
|
+
slugs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
799
|
+
} catch {
|
|
800
|
+
return [];
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const active = [];
|
|
804
|
+
for (const slug of slugs) {
|
|
805
|
+
const p = path.join(featuresDir, slug, 'dossier.md');
|
|
806
|
+
try {
|
|
807
|
+
const raw = await fs.readFile(p, 'utf8');
|
|
808
|
+
const statusMatch = raw.match(/^status:\s*(\S+)\s*$/m);
|
|
809
|
+
const updatedMatch = raw.match(/^last_updated_at:\s*(\S+)\s*$/m);
|
|
810
|
+
if (!statusMatch || statusMatch[1] !== 'active') continue;
|
|
811
|
+
const relPath = `${CONTEXT_DIR}/features/${slug}/dossier.md`;
|
|
812
|
+
active.push({
|
|
813
|
+
relPath,
|
|
814
|
+
slug,
|
|
815
|
+
lastUpdatedAt: updatedMatch ? updatedMatch[1] : null,
|
|
816
|
+
title: `Feature Dossier (${slug})`,
|
|
817
|
+
group: 'dossier',
|
|
818
|
+
readWhen: `active feature "${slug}" synthesis — why, what, code map, agent trail`,
|
|
819
|
+
tags: ['dossier', 'feature', 'active'],
|
|
820
|
+
exists: true
|
|
821
|
+
});
|
|
822
|
+
} catch {
|
|
823
|
+
// skip unreadable
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// Sort by last_updated_at descending (most recent first)
|
|
828
|
+
active.sort((a, b) => {
|
|
829
|
+
if (!a.lastUpdatedAt && !b.lastUpdatedAt) return 0;
|
|
830
|
+
if (!a.lastUpdatedAt) return 1;
|
|
831
|
+
if (!b.lastUpdatedAt) return -1;
|
|
832
|
+
return b.lastUpdatedAt.localeCompare(a.lastUpdatedAt);
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
return active;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function rankDossier(dossier, { agent, goal }, rank) {
|
|
839
|
+
// Base score: between PRD (45) and bootstrap (65). Most recent dossier gets 60.
|
|
840
|
+
let score = 60 - rank * 5;
|
|
841
|
+
const reasons = [`active feature dossier (${dossier.slug})`];
|
|
842
|
+
const lookupText = `${normalizeForLookup(agent)} ${normalizeForLookup(goal)}`.trim();
|
|
843
|
+
if (lookupText.includes(dossier.slug.replace(/-/g, ' '))) {
|
|
844
|
+
score += 15;
|
|
845
|
+
reasons.push('matches active feature slug');
|
|
846
|
+
}
|
|
847
|
+
if (/(dev|architect|qa|implement|feature|dossier)/.test(lookupText)) {
|
|
848
|
+
score += 10;
|
|
849
|
+
reasons.push('agent/goal matches dossier context');
|
|
850
|
+
}
|
|
851
|
+
return { score: Math.max(score, 0), reasons };
|
|
852
|
+
}
|
|
853
|
+
|
|
740
854
|
async function createContextPack({
|
|
741
855
|
targetDir,
|
|
742
856
|
agent = '',
|
|
@@ -752,15 +866,25 @@ async function createContextPack({
|
|
|
752
866
|
: 8;
|
|
753
867
|
|
|
754
868
|
const catalog = (await collectContextCatalog(targetDir)).filter((doc) => doc.exists);
|
|
755
|
-
|
|
756
|
-
|
|
869
|
+
|
|
870
|
+
// Inject active dossiers as ranked sources (reference, not inline copy)
|
|
871
|
+
const activeDossiers = await collectActiveDossiers(targetDir);
|
|
872
|
+
const dossierDocs = activeDossiers.map((d, i) => {
|
|
873
|
+
const rank = rankDossier(d, { agent, goal }, i);
|
|
874
|
+
return { ...d, score: rank.score, reason: rank.reasons.join('; ') };
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
const ranked = [
|
|
878
|
+
...catalog.map((doc) => {
|
|
757
879
|
const rank = rankContextDoc(doc, { agent, goal, module });
|
|
758
880
|
return {
|
|
759
881
|
...doc,
|
|
760
882
|
score: rank.score,
|
|
761
883
|
reason: rank.reasons.join('; ') || doc.readWhen
|
|
762
884
|
};
|
|
763
|
-
})
|
|
885
|
+
}),
|
|
886
|
+
...dossierDocs
|
|
887
|
+
]
|
|
764
888
|
.filter((doc) => doc.score > 0)
|
|
765
889
|
.sort((a, b) => b.score - a.score || a.relPath.localeCompare(b.relPath));
|
|
766
890
|
|
|
@@ -826,6 +950,11 @@ module.exports = {
|
|
|
826
950
|
SCAN_FOLDERS_FILE,
|
|
827
951
|
SCAN_AIOSON_FILE,
|
|
828
952
|
CONTEXT_PACK_FILE,
|
|
953
|
+
BOOTSTRAP_DIR,
|
|
954
|
+
BOOTSTRAP_WHAT_IS,
|
|
955
|
+
BOOTSTRAP_HOW_IT_WORKS,
|
|
956
|
+
BOOTSTRAP_WHAT_IT_DOES,
|
|
957
|
+
BOOTSTRAP_CURRENT_STATE,
|
|
829
958
|
buildModuleMemoryRelativePath,
|
|
830
959
|
buildSpecCurrentMarkdown,
|
|
831
960
|
buildSpecHistoryMarkdown,
|
package/src/context-writer.js
CHANGED
|
@@ -60,7 +60,7 @@ function normalizeBoolean(value, fallback = false) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
function renderProjectContext(data) {
|
|
63
|
-
const language = data.conversationLanguage || 'en';
|
|
63
|
+
const language = data.interactionLanguage || data.conversationLanguage || 'en';
|
|
64
64
|
const codeCommentLanguage = data.codeCommentLanguage || language;
|
|
65
65
|
const generatedAt = data.generatedAt || new Date().toISOString();
|
|
66
66
|
const designSkill = data.designSkill || '';
|
|
@@ -80,6 +80,7 @@ profile: "${data.profile}"
|
|
|
80
80
|
framework: "${data.framework}"
|
|
81
81
|
framework_installed: ${data.frameworkInstalled ? 'true' : 'false'}
|
|
82
82
|
classification: "${data.classification}"
|
|
83
|
+
interaction_language: "${language}"
|
|
83
84
|
conversation_language: "${language}"
|
|
84
85
|
design_skill: "${designSkill}"
|
|
85
86
|
test_runner: "${testRunner}"
|
package/src/context.js
CHANGED
|
@@ -86,6 +86,23 @@ function isValidLanguageTag(value) {
|
|
|
86
86
|
return /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$/.test(tag);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
function normalizeLanguageTag(value, fallback = 'en') {
|
|
90
|
+
const tag = String(value || '').trim().replace(/_/g, '-');
|
|
91
|
+
if (!tag) return fallback;
|
|
92
|
+
return isValidLanguageTag(tag) ? tag : fallback;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getInteractionLanguage(data, fallback = 'en') {
|
|
96
|
+
if (!data || typeof data !== 'object') return fallback;
|
|
97
|
+
if (Object.prototype.hasOwnProperty.call(data, 'interaction_language')) {
|
|
98
|
+
return normalizeLanguageTag(data.interaction_language, fallback);
|
|
99
|
+
}
|
|
100
|
+
if (Object.prototype.hasOwnProperty.call(data, 'conversation_language')) {
|
|
101
|
+
return normalizeLanguageTag(data.conversation_language, fallback);
|
|
102
|
+
}
|
|
103
|
+
return fallback;
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
function validateContextData(data) {
|
|
90
107
|
const issues = [];
|
|
91
108
|
|
|
@@ -148,6 +165,18 @@ function validateContextData(data) {
|
|
|
148
165
|
});
|
|
149
166
|
}
|
|
150
167
|
|
|
168
|
+
if (
|
|
169
|
+
Object.prototype.hasOwnProperty.call(data, 'interaction_language') &&
|
|
170
|
+
!isValidLanguageTag(data.interaction_language)
|
|
171
|
+
) {
|
|
172
|
+
issues.push({
|
|
173
|
+
id: 'context:interaction_language:format',
|
|
174
|
+
key: 'doctor.context_interaction_language_format',
|
|
175
|
+
params: {},
|
|
176
|
+
hintKey: 'doctor.context_interaction_language_format_hint'
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
151
180
|
if (
|
|
152
181
|
Object.prototype.hasOwnProperty.call(data, 'conversation_language') &&
|
|
153
182
|
!isValidLanguageTag(data.conversation_language)
|
|
@@ -212,6 +241,7 @@ module.exports = {
|
|
|
212
241
|
parseYamlFrontmatter,
|
|
213
242
|
validateContextData,
|
|
214
243
|
validateProjectContextFile,
|
|
215
|
-
isValidLanguageTag
|
|
244
|
+
isValidLanguageTag,
|
|
245
|
+
normalizeLanguageTag,
|
|
246
|
+
getInteractionLanguage
|
|
216
247
|
};
|
|
217
|
-
|
package/src/doctor.js
CHANGED
|
@@ -5,8 +5,8 @@ const path = require('node:path');
|
|
|
5
5
|
const { REQUIRED_FILES } = require('./constants');
|
|
6
6
|
const { installTemplate, TEMPLATE_DIR } = require('./installer');
|
|
7
7
|
const { exists, copyFileWithDir } = require('./utils');
|
|
8
|
-
const { validateProjectContextFile } = require('./context');
|
|
9
|
-
const { applyAgentLocale
|
|
8
|
+
const { validateProjectContextFile, getInteractionLanguage } = require('./context');
|
|
9
|
+
const { applyAgentLocale } = require('./locales');
|
|
10
10
|
|
|
11
11
|
function parseMajor(version) {
|
|
12
12
|
const cleaned = String(version || '').replace(/^v/, '');
|
|
@@ -34,6 +34,14 @@ const GEMINI_COMMAND_EXPECTATIONS = [
|
|
|
34
34
|
{ file: '.gemini/commands/aios-orchestrator.toml', agent: 'orchestrator' }
|
|
35
35
|
];
|
|
36
36
|
|
|
37
|
+
const DESIGN_GOVERNANCE_FILES = [
|
|
38
|
+
'.aioson/design-docs/code-reuse.md',
|
|
39
|
+
'.aioson/design-docs/componentization.md',
|
|
40
|
+
'.aioson/design-docs/file-size.md',
|
|
41
|
+
'.aioson/design-docs/folder-structure.md',
|
|
42
|
+
'.aioson/design-docs/naming.md'
|
|
43
|
+
];
|
|
44
|
+
|
|
37
45
|
const GATEWAY_FILE_BY_CHECK_ID = {
|
|
38
46
|
'gateway:claude:contract': 'CLAUDE.md',
|
|
39
47
|
'gateway:codex:contract': 'AGENTS.md',
|
|
@@ -79,6 +87,16 @@ async function runDoctor(targetDir) {
|
|
|
79
87
|
});
|
|
80
88
|
}
|
|
81
89
|
|
|
90
|
+
for (const rel of DESIGN_GOVERNANCE_FILES) {
|
|
91
|
+
checks.push({
|
|
92
|
+
id: `design-governance:${rel}`,
|
|
93
|
+
key: 'doctor.required_file',
|
|
94
|
+
params: { rel },
|
|
95
|
+
ok: await exists(path.join(targetDir, rel)),
|
|
96
|
+
hintKey: 'doctor.context_hint'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
82
100
|
const gatewayChecks = [
|
|
83
101
|
{
|
|
84
102
|
id: 'gateway:claude:contract',
|
|
@@ -130,7 +148,7 @@ async function runDoctor(targetDir) {
|
|
|
130
148
|
key: 'doctor.gateway_gemini_command_pointer',
|
|
131
149
|
params: { file: expectation.file },
|
|
132
150
|
ok: await fileContainsAll(commandPath, [
|
|
133
|
-
|
|
151
|
+
`@{ .aioson/agents/${expectation.agent}.md }`
|
|
134
152
|
]),
|
|
135
153
|
hintKey: 'doctor.gateway_gemini_command_pointer_hint',
|
|
136
154
|
hintParams: {
|
|
@@ -250,14 +268,36 @@ async function applyDoctorFixes(targetDir, report, options = {}) {
|
|
|
250
268
|
});
|
|
251
269
|
}
|
|
252
270
|
|
|
271
|
+
const missingDesignGovernanceFiles = report.checks
|
|
272
|
+
.filter((check) => !check.ok && check.id.startsWith('design-governance:'))
|
|
273
|
+
.map((check) => check.params.rel);
|
|
274
|
+
|
|
275
|
+
if (missingDesignGovernanceFiles.length > 0) {
|
|
276
|
+
const restored = await restoreTemplateFiles(targetDir, missingDesignGovernanceFiles, { dryRun });
|
|
277
|
+
if (restored.length > 0) changedCount += restored.length;
|
|
278
|
+
actions.push({
|
|
279
|
+
id: 'design_governance',
|
|
280
|
+
applied: restored.length > 0,
|
|
281
|
+
count: restored.length,
|
|
282
|
+
missingCount: missingDesignGovernanceFiles.length
|
|
283
|
+
});
|
|
284
|
+
} else {
|
|
285
|
+
actions.push({
|
|
286
|
+
id: 'design_governance',
|
|
287
|
+
applied: false,
|
|
288
|
+
skipped: true,
|
|
289
|
+
count: 0,
|
|
290
|
+
missingCount: 0
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
253
294
|
if (
|
|
254
295
|
report.contextValidation &&
|
|
255
296
|
report.contextValidation.parsed &&
|
|
256
297
|
report.contextValidation.valid &&
|
|
257
|
-
report.contextValidation.data
|
|
258
|
-
report.contextValidation.data.conversation_language
|
|
298
|
+
report.contextValidation.data
|
|
259
299
|
) {
|
|
260
|
-
const locale =
|
|
300
|
+
const locale = getInteractionLanguage(report.contextValidation.data, 'en');
|
|
261
301
|
const localeResult = await applyAgentLocale(targetDir, locale, { dryRun });
|
|
262
302
|
if (localeResult.copied.length > 0) changedCount += localeResult.copied.length;
|
|
263
303
|
actions.push({
|