@jaimevalasek/aioson 1.3.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -1
- package/LICENSE +661 -21
- package/README.md +22 -3
- package/docs/en/squad-dashboard.md +372 -0
- package/docs/openclaw-bridge.md +308 -0
- package/docs/pt/README.md +62 -2
- package/docs/pt/advisor-spec.md +5 -5
- package/docs/pt/agentes-customizados.md +670 -0
- package/docs/pt/agentes.md +235 -23
- package/docs/pt/automacao-squads.md +407 -0
- package/docs/pt/cenarios.md +49 -5
- package/docs/pt/clientes-ai.md +62 -0
- package/docs/pt/comandos-cli.md +226 -17
- package/docs/pt/deyvin.md +115 -0
- package/docs/pt/genome-3.0-spec.md +11 -11
- package/docs/pt/inicio-rapido.md +63 -2
- package/docs/pt/memoria-contexto.md +255 -0
- package/docs/pt/output-strategy-delivery.md +655 -0
- package/docs/pt/profiler-system.md +17 -17
- package/docs/pt/runtime-observability.md +5 -1
- package/docs/pt/skills.md +175 -0
- package/docs/pt/squad-dashboard.md +373 -0
- package/docs/pt/{squad-genoma.md → squad-genome.md} +81 -75
- package/docs/testing/genome-2.0-matrix.md +5 -5
- package/docs/testing/genome-2.0-rollout.md +10 -10
- package/package.json +4 -4
- package/src/agents.js +21 -5
- package/src/backup-local.js +74 -0
- package/src/backup-provider.js +303 -0
- package/src/cli.js +276 -2
- package/src/commands/agents.js +22 -4
- package/src/commands/backup-local-cmd.js +25 -0
- package/src/commands/backup.js +533 -0
- package/src/commands/cloud.js +17 -17
- package/src/commands/context-pack.js +45 -0
- package/src/commands/implementation-plan.js +340 -0
- package/src/commands/learning.js +134 -0
- package/src/commands/live.js +1583 -0
- package/src/commands/runtime.js +1075 -2
- package/src/commands/scan-project.js +288 -24
- package/src/commands/setup-context.js +30 -2
- package/src/commands/skill.js +558 -0
- package/src/commands/squad-agent-create.js +788 -0
- package/src/commands/squad-daemon.js +209 -0
- package/src/commands/squad-dashboard.js +39 -0
- package/src/commands/squad-deploy.js +64 -0
- package/src/commands/squad-doctor.js +103 -1
- package/src/commands/squad-investigate.js +261 -0
- package/src/commands/squad-learning.js +209 -0
- package/src/commands/squad-mcp.js +270 -0
- package/src/commands/squad-pipeline.js +247 -1
- package/src/commands/squad-plan.js +329 -0
- package/src/commands/squad-processes.js +56 -0
- package/src/commands/squad-recovery.js +42 -0
- package/src/commands/squad-roi.js +291 -0
- package/src/commands/squad-score.js +250 -0
- package/src/commands/squad-status.js +38 -2
- package/src/commands/squad-validate.js +118 -1
- package/src/commands/squad-webhook.js +160 -0
- package/src/commands/squad-worker.js +191 -0
- package/src/commands/squad-worktrees.js +75 -0
- package/src/commands/test-agents.js +6 -1
- package/src/commands/web-map.js +70 -0
- package/src/commands/web-scrape.js +71 -0
- package/src/commands/workflow-next.js +8 -1
- package/src/commands/workflow-status.js +250 -0
- package/src/constants.js +88 -16
- package/src/context-memory.js +837 -0
- package/src/context-writer.js +47 -1
- package/src/delivery-runner.js +319 -0
- package/src/genome-files.js +1 -1
- package/src/genome-format.js +1 -1
- package/src/i18n/messages/en.js +333 -8
- package/src/i18n/messages/es.js +240 -6
- package/src/i18n/messages/fr.js +239 -5
- package/src/i18n/messages/pt-BR.js +330 -12
- package/src/installer.js +30 -2
- package/src/lib/genomes/compat.js +1 -1
- package/src/lib/webhook-server.js +328 -0
- package/src/mcp-connectors/registry.js +602 -0
- package/src/runtime-store.js +1037 -42
- package/src/session-handoff.js +77 -0
- package/src/squad/external-session.js +180 -0
- package/src/squad/inter-squad.js +74 -0
- package/src/squad/recovery-context.js +201 -0
- package/src/squad/worktree-manager.js +114 -0
- package/src/squad-daemon.js +490 -0
- package/src/squad-dashboard/api.js +223 -0
- package/src/squad-dashboard/attachment-handler.js +93 -0
- package/src/squad-dashboard/context-monitor.js +157 -0
- package/src/squad-dashboard/execution-logs.js +115 -0
- package/src/squad-dashboard/hunk-review.js +209 -0
- package/src/squad-dashboard/metrics.js +133 -0
- package/src/squad-dashboard/process-monitor.js +125 -0
- package/src/squad-dashboard/renderer.js +858 -0
- package/src/squad-dashboard/server.js +232 -0
- package/src/squad-dashboard/styles.js +525 -0
- package/src/squad-dashboard/token-tracker.js +99 -0
- package/src/web.js +284 -0
- package/src/worker-runner.js +339 -0
- package/template/.aioson/agents/analyst.md +40 -9
- package/template/.aioson/agents/architect.md +24 -5
- package/template/.aioson/agents/dev.md +254 -25
- package/template/.aioson/agents/deyvin.md +174 -0
- package/template/.aioson/agents/discovery-design-doc.md +25 -1
- package/template/.aioson/agents/{genoma.md → genome.md} +20 -20
- package/template/.aioson/agents/neo.md +152 -0
- package/template/.aioson/agents/orache.md +388 -0
- package/template/.aioson/agents/orchestrator.md +63 -2
- package/template/.aioson/agents/pair.md +5 -0
- package/template/.aioson/agents/pm.md +17 -5
- package/template/.aioson/agents/product.md +113 -29
- package/template/.aioson/agents/profiler-enricher.md +1 -1
- package/template/.aioson/agents/profiler-forge.md +9 -9
- package/template/.aioson/agents/profiler-researcher.md +1 -1
- package/template/.aioson/agents/qa.md +18 -5
- package/template/.aioson/agents/setup.md +138 -18
- package/template/.aioson/agents/sheldon.md +603 -0
- package/template/.aioson/agents/squad.md +866 -28
- package/template/.aioson/agents/tester.md +254 -0
- package/template/.aioson/agents/ux-ui.md +289 -34
- package/template/.aioson/config.md +181 -0
- package/template/.aioson/context/spec.md.template +17 -0
- package/template/.aioson/genomes/.gitkeep +0 -0
- package/template/.aioson/installed-skills/.gitkeep +0 -0
- package/template/.aioson/locales/en/agents/analyst.md +34 -4
- package/template/.aioson/locales/en/agents/architect.md +18 -0
- package/template/.aioson/locales/en/agents/dev.md +155 -11
- package/template/.aioson/locales/en/agents/deyvin.md +137 -0
- package/template/.aioson/locales/en/agents/{genoma.md → genome.md} +14 -14
- package/template/.aioson/locales/en/agents/neo.md +8 -0
- package/template/.aioson/locales/en/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/en/agents/pair.md +5 -0
- package/template/.aioson/locales/en/agents/pm.md +7 -0
- package/template/.aioson/locales/en/agents/product.md +35 -17
- package/template/.aioson/locales/en/agents/qa.md +56 -0
- package/template/.aioson/locales/en/agents/setup.md +53 -6
- package/template/.aioson/locales/en/agents/sheldon.md +340 -0
- package/template/.aioson/locales/en/agents/squad.md +203 -15
- package/template/.aioson/locales/en/agents/ux-ui.md +383 -35
- package/template/.aioson/locales/es/agents/analyst.md +24 -4
- package/template/.aioson/locales/es/agents/architect.md +18 -0
- package/template/.aioson/locales/es/agents/dev.md +136 -9
- package/template/.aioson/locales/es/agents/deyvin.md +97 -0
- package/template/.aioson/locales/es/agents/{genoma.md → genome.md} +13 -13
- package/template/.aioson/locales/es/agents/neo.md +48 -0
- package/template/.aioson/locales/es/agents/orache.md +103 -0
- package/template/.aioson/locales/es/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/es/agents/pair.md +5 -0
- package/template/.aioson/locales/es/agents/pm.md +7 -0
- package/template/.aioson/locales/es/agents/product.md +13 -3
- package/template/.aioson/locales/es/agents/qa.md +33 -0
- package/template/.aioson/locales/es/agents/setup.md +30 -6
- package/template/.aioson/locales/es/agents/sheldon.md +192 -0
- package/template/.aioson/locales/es/agents/squad.md +284 -15
- package/template/.aioson/locales/es/agents/ux-ui.md +34 -25
- package/template/.aioson/locales/fr/agents/analyst.md +24 -4
- package/template/.aioson/locales/fr/agents/architect.md +18 -0
- package/template/.aioson/locales/fr/agents/dev.md +136 -9
- package/template/.aioson/locales/fr/agents/deyvin.md +97 -0
- package/template/.aioson/locales/fr/agents/{genoma.md → genome.md} +7 -7
- package/template/.aioson/locales/fr/agents/neo.md +48 -0
- package/template/.aioson/locales/fr/agents/orache.md +104 -0
- package/template/.aioson/locales/fr/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/fr/agents/pair.md +5 -0
- package/template/.aioson/locales/fr/agents/pm.md +7 -0
- package/template/.aioson/locales/fr/agents/product.md +13 -3
- package/template/.aioson/locales/fr/agents/qa.md +33 -0
- package/template/.aioson/locales/fr/agents/setup.md +30 -6
- package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
- package/template/.aioson/locales/fr/agents/squad.md +279 -10
- package/template/.aioson/locales/fr/agents/ux-ui.md +34 -25
- package/template/.aioson/locales/pt-BR/agents/analyst.md +45 -4
- package/template/.aioson/locales/pt-BR/agents/architect.md +29 -0
- package/template/.aioson/locales/pt-BR/agents/dev.md +167 -15
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +137 -0
- package/template/.aioson/locales/pt-BR/agents/{genoma.md → genome.md} +49 -49
- package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
- package/template/.aioson/locales/pt-BR/agents/orache.md +137 -0
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +62 -2
- package/template/.aioson/locales/pt-BR/agents/pair.md +5 -0
- package/template/.aioson/locales/pt-BR/agents/pm.md +7 -0
- package/template/.aioson/locales/pt-BR/agents/product.md +43 -20
- package/template/.aioson/locales/pt-BR/agents/qa.md +67 -0
- package/template/.aioson/locales/pt-BR/agents/setup.md +53 -6
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
- package/template/.aioson/locales/pt-BR/agents/squad.md +591 -47
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +369 -22
- package/template/.aioson/my-agents/.gitkeep +0 -0
- package/template/.aioson/rules/.gitkeep +0 -0
- package/template/.aioson/rules/squad/.gitkeep +0 -0
- package/template/.aioson/rules/squad/README.md +50 -0
- package/template/.aioson/schemas/genome-meta.schema.json +1 -1
- package/template/.aioson/schemas/genome.schema.json +1 -1
- package/template/.aioson/schemas/squad-blueprint.schema.json +32 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +434 -1
- package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
- package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
- package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
- package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
- package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +203 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +407 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +272 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +524 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +277 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +289 -0
- package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +437 -0
- package/template/.aioson/skills/design/interface-design/SKILL.md +47 -0
- package/template/.aioson/skills/design/interface-design/references/components-and-states.md +105 -0
- package/template/.aioson/skills/design/interface-design/references/design-directions.md +101 -0
- package/template/.aioson/skills/design/interface-design/references/handoff-and-quality.md +71 -0
- package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +74 -0
- package/template/.aioson/skills/design/interface-design/references/tokens-and-depth.md +173 -0
- package/template/.aioson/skills/design/premium-command-center-ui/SKILL.md +62 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/operations.md +74 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/patterns.md +116 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/validation.md +47 -0
- package/template/.aioson/skills/design/premium-command-center-ui/references/visual-system.md +215 -0
- package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
- package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
- package/template/.aioson/skills/design-system/SKILL.md +92 -0
- package/template/.aioson/skills/design-system/cognitive-core-ui.skill +0 -0
- package/template/.aioson/skills/design-system/components/SKILL.md +274 -0
- package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/dashboards/SKILL.md +184 -0
- package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/foundations/SKILL.md +250 -0
- package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/motion/SKILL.md +197 -0
- package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/patterns/SKILL.md +231 -0
- package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
- package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
- package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
- package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
- package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
- package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
- package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
- package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
- package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
- package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
- package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
- package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
- package/template/.aioson/skills/squad/SKILL.md +58 -0
- package/template/.aioson/skills/squad/domains/.gitkeep +0 -0
- package/template/.aioson/skills/squad/formats/.gitkeep +0 -0
- package/template/.aioson/skills/squad/formats/catalog.json +15 -0
- package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
- package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
- package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
- package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
- package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
- package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
- package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
- package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
- package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
- package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
- package/template/.aioson/skills/squad/patterns/.gitkeep +0 -0
- package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
- package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
- package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
- package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
- package/template/.aioson/skills/squad/references/.gitkeep +0 -0
- package/template/.aioson/skills/squad/references/checklist-templates.md +122 -0
- package/template/.aioson/skills/squad/references/executor-archetypes.md +123 -0
- package/template/.aioson/skills/squad/references/workflow-templates.md +169 -0
- package/template/.aioson/skills/static/debugging-protocol.md +42 -0
- package/template/.aioson/skills/static/git-worktrees.md +36 -0
- package/template/.aioson/tasks/implementation-plan.md +307 -0
- package/template/.aioson/tasks/squad-create.md +1 -1
- package/template/.aioson/tasks/squad-design.md +28 -0
- package/template/.aioson/tasks/squad-execution-plan.md +279 -0
- package/template/.aioson/tasks/squad-export.md +1 -1
- package/template/.aioson/tasks/squad-investigate.md +44 -0
- package/template/.aioson/tasks/squad-learning-review.md +44 -0
- package/template/.aioson/tasks/squad-output-config.md +177 -0
- package/template/.aioson/tasks/squad-profile.md +48 -0
- package/template/.aioson/tasks/squad-review.md +61 -0
- package/template/.aioson/tasks/squad-task-decompose.md +66 -0
- package/template/.aioson/tasks/squad-validate.md +1 -1
- package/template/.claude/commands/aioson/agent/deyvin.md +5 -0
- package/template/.claude/commands/aioson/agent/discovery-design-doc.md +5 -0
- package/template/.claude/commands/aioson/agent/genome.md +5 -0
- package/template/.claude/commands/aioson/agent/neo.md +5 -0
- package/template/.claude/commands/aioson/agent/product.md +5 -0
- package/template/.claude/commands/aioson/agent/profiler-enricher.md +5 -0
- package/template/.claude/commands/aioson/agent/profiler-forge.md +5 -0
- package/template/.claude/commands/aioson/agent/profiler-researcher.md +5 -0
- package/template/.claude/commands/aioson/agent/squad.md +5 -0
- package/template/.claude/commands/aioson/agent/tester.md +5 -0
- package/template/.gemini/GEMINI.md +3 -0
- package/template/.gemini/commands/aios-deyvin.toml +6 -0
- package/template/.gemini/commands/aios-neo.toml +4 -0
- package/template/.gemini/commands/aios-pair.toml +6 -0
- package/template/.gemini/commands/aios-tester.toml +6 -0
- package/template/AGENTS.md +37 -6
- package/template/CLAUDE.md +34 -4
- package/template/OPENCODE.md +8 -2
- package/template/squad-searches/.gitkeep +0 -0
- package/template/.aioson/skills/static/interface-design.md +0 -372
- package/template/.aioson/skills/static/premium-command-center-ui.md +0 -190
- /package/template/.aioson/{genomas → docs}/.gitkeep +0 -0
- /package/template/.claude/commands/aioson/{analyst.md → agent/analyst.md} +0 -0
- /package/template/.claude/commands/aioson/{architect.md → agent/architect.md} +0 -0
- /package/template/.claude/commands/aioson/{dev.md → agent/dev.md} +0 -0
- /package/template/.claude/commands/aioson/{orchestrator.md → agent/orchestrator.md} +0 -0
- /package/template/.claude/commands/aioson/{pm.md → agent/pm.md} +0 -0
- /package/template/.claude/commands/aioson/{qa.md → agent/qa.md} +0 -0
- /package/template/.claude/commands/aioson/{setup.md → agent/setup.md} +0 -0
- /package/template/.claude/commands/aioson/{ux-ui.md → agent/ux-ui.md} +0 -0
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { exists, ensureDir } = require('../utils');
|
|
6
|
+
|
|
7
|
+
const MY_AGENTS_DIR = '.aioson/my-agents';
|
|
8
|
+
const SQUADS_DIR = '.aioson/squads';
|
|
9
|
+
|
|
10
|
+
const VALID_TYPES = ['agent', 'assistant', 'clone', 'worker'];
|
|
11
|
+
const VALID_TIERS = ['0', '1', '2', '3'];
|
|
12
|
+
const VALID_DISC = [
|
|
13
|
+
'dominant-driver', 'influential-expressive', 'steady-amiable',
|
|
14
|
+
'compliant-analytical', 'dominant-influential', 'influential-steady',
|
|
15
|
+
'steady-compliant', 'compliant-dominant'
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
function resolveTargetDir(args) {
|
|
19
|
+
return path.resolve(process.cwd(), args[0] || '.');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function slugify(name) {
|
|
23
|
+
return name
|
|
24
|
+
.toLowerCase()
|
|
25
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
26
|
+
.replace(/^-|-$/g, '');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Agent template builder — inspired by AIOX create-agent v3.0 but adapted
|
|
31
|
+
// for aioson's markdown-agent ecosystem (Claude Code, Codex, Gemini CLI).
|
|
32
|
+
//
|
|
33
|
+
// Levels:
|
|
34
|
+
// 0 — Infrastructure (skills, dependencies, file references)
|
|
35
|
+
// 1 — Identity (who the agent is)
|
|
36
|
+
// 2 — Operational (how the agent works)
|
|
37
|
+
// 3 — Voice DNA (how the agent communicates — for assistant/clone types)
|
|
38
|
+
// 4 — Quality (how to know the work is good)
|
|
39
|
+
// 5 — Integration (hand-offs and synergies)
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
function buildAgentTemplate(slug, opts) {
|
|
43
|
+
const {
|
|
44
|
+
mission = '',
|
|
45
|
+
focus = [],
|
|
46
|
+
scope = 'my-agents',
|
|
47
|
+
squadSlug = null,
|
|
48
|
+
squadName = null,
|
|
49
|
+
type = 'agent',
|
|
50
|
+
tier = null,
|
|
51
|
+
disc = null,
|
|
52
|
+
domain = null,
|
|
53
|
+
specialist = null,
|
|
54
|
+
withInfra = false
|
|
55
|
+
} = opts;
|
|
56
|
+
|
|
57
|
+
const lines = [];
|
|
58
|
+
|
|
59
|
+
// ── Header ──────────────────────────────────────────────────────────────
|
|
60
|
+
lines.push(`# Agent @${slug}`);
|
|
61
|
+
lines.push('');
|
|
62
|
+
|
|
63
|
+
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}` : ''} -->`;
|
|
66
|
+
lines.push(identity);
|
|
67
|
+
lines.push('');
|
|
68
|
+
lines.push(`> ⚡ **ACTIVATED** — Execute immediately as @${slug}.`);
|
|
69
|
+
lines.push('');
|
|
70
|
+
|
|
71
|
+
// ── Project rules ───────────────────────────────────────────────────────
|
|
72
|
+
if (scope === 'squad' && squadSlug) {
|
|
73
|
+
lines.push(`> **Project rules**: Before starting, check \`.aioson/rules/\` in the project root.`);
|
|
74
|
+
lines.push(`> For each \`.md\` file found: read YAML frontmatter. Load if \`agents:\` is absent (universal),`);
|
|
75
|
+
lines.push(`> or if \`agents:\` includes \`squad:${squadSlug}/${slug}\` or \`squad:${squadSlug}\`. Otherwise skip.`);
|
|
76
|
+
} else {
|
|
77
|
+
lines.push(`> **Project rules**: Before starting, check \`.aioson/rules/\` in the project root.`);
|
|
78
|
+
lines.push(`> For each \`.md\` file found: read YAML frontmatter. Load if \`agents:\` is absent (universal),`);
|
|
79
|
+
lines.push(`> or if \`agents:\` includes \`${slug}\`. Otherwise skip.`);
|
|
80
|
+
}
|
|
81
|
+
lines.push('');
|
|
82
|
+
|
|
83
|
+
// ── Level 1: Identity ───────────────────────────────────────────────────
|
|
84
|
+
lines.push('## Mission');
|
|
85
|
+
lines.push(mission || '[Define the agent mission — what problem does this agent solve?]');
|
|
86
|
+
lines.push('');
|
|
87
|
+
|
|
88
|
+
if (scope === 'squad' && squadSlug) {
|
|
89
|
+
lines.push('## Quick context');
|
|
90
|
+
lines.push(`Squad: ${squadName || squadSlug} | Agent: @${slug} | Type: ${type}${tier ? ` | Tier: ${tier}` : ''}`);
|
|
91
|
+
if (domain) lines.push(`Domain: ${domain}`);
|
|
92
|
+
lines.push('');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (specialist) {
|
|
96
|
+
lines.push('## Specialist');
|
|
97
|
+
lines.push(`Based on: **${specialist}**`);
|
|
98
|
+
lines.push('[Add source material: books, articles, talks, methodologies that shaped this agent]');
|
|
99
|
+
lines.push('');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (disc) {
|
|
103
|
+
lines.push('## Behavioral profile');
|
|
104
|
+
lines.push(`DISC: ${disc}`);
|
|
105
|
+
lines.push('');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ── Level 2: Operational ────────────────────────────────────────────────
|
|
109
|
+
lines.push('## Core principles');
|
|
110
|
+
lines.push('[5-10 fundamental beliefs that guide every decision this agent makes]');
|
|
111
|
+
lines.push('- [Principle 1]');
|
|
112
|
+
lines.push('- [Principle 2]');
|
|
113
|
+
lines.push('- [Principle 3]');
|
|
114
|
+
lines.push('');
|
|
115
|
+
|
|
116
|
+
if (focus.length > 0) {
|
|
117
|
+
lines.push('## Focus');
|
|
118
|
+
for (const f of focus) lines.push(`- ${f}`);
|
|
119
|
+
} else {
|
|
120
|
+
lines.push('## Focus');
|
|
121
|
+
lines.push('- [Primary capability or focus area]');
|
|
122
|
+
lines.push('- [Secondary capability]');
|
|
123
|
+
}
|
|
124
|
+
lines.push('');
|
|
125
|
+
|
|
126
|
+
lines.push('## Operational framework');
|
|
127
|
+
lines.push('[Step-by-step methodology — the deterministic process this agent follows]');
|
|
128
|
+
lines.push('');
|
|
129
|
+
lines.push('1. **Understand** — Read context, inputs, and constraints');
|
|
130
|
+
lines.push('2. **Analyze** — Identify what is needed and what already exists');
|
|
131
|
+
lines.push('3. **Execute** — Produce the output following the methodology');
|
|
132
|
+
lines.push('4. **Validate** — Check against quality criteria before delivering');
|
|
133
|
+
lines.push('');
|
|
134
|
+
|
|
135
|
+
// ── Level 3: Voice DNA (assistant/clone types) ──────────────────────────
|
|
136
|
+
if (type === 'assistant' || type === 'clone') {
|
|
137
|
+
lines.push('## Voice DNA');
|
|
138
|
+
lines.push('');
|
|
139
|
+
lines.push('### Sentence starters');
|
|
140
|
+
lines.push('[How this agent opens responses — categorized by mode]');
|
|
141
|
+
lines.push('- **Explaining:** "[...]", "[...]"');
|
|
142
|
+
lines.push('- **Challenging:** "[...]", "[...]"');
|
|
143
|
+
lines.push('- **Recommending:** "[...]", "[...]"');
|
|
144
|
+
lines.push('');
|
|
145
|
+
lines.push('### Vocabulary');
|
|
146
|
+
lines.push('**Always use:** [8+ domain-specific terms this agent prefers]');
|
|
147
|
+
lines.push('');
|
|
148
|
+
lines.push('**Never use:** [5+ terms this agent avoids]');
|
|
149
|
+
lines.push('');
|
|
150
|
+
lines.push('### Metaphors');
|
|
151
|
+
lines.push('[5+ domain metaphors this agent uses naturally]');
|
|
152
|
+
lines.push('- [Metaphor 1]');
|
|
153
|
+
lines.push('- [Metaphor 2]');
|
|
154
|
+
lines.push('');
|
|
155
|
+
lines.push('### Emotional states');
|
|
156
|
+
lines.push('[How the agent modulates tone based on context]');
|
|
157
|
+
lines.push('- **Teaching:** patient, detailed, with examples');
|
|
158
|
+
lines.push('- **Reviewing:** direct, precise, no filler');
|
|
159
|
+
lines.push('- **Brainstorming:** energetic, expansive, provocative');
|
|
160
|
+
lines.push('');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ── Response standard ───────────────────────────────────────────────────
|
|
164
|
+
lines.push('## Response standard');
|
|
165
|
+
if (type === 'worker') {
|
|
166
|
+
lines.push('Execute the task deterministically. No creative deviation. Follow the process exactly.');
|
|
167
|
+
} else if (type === 'clone') {
|
|
168
|
+
lines.push('[Define the delivery format — tone, structure, length, level of detail]');
|
|
169
|
+
lines.push('Write as the specialist would write. Match their cadence, vocabulary, and reasoning style.');
|
|
170
|
+
} else {
|
|
171
|
+
lines.push('[Define the delivery format — tone, structure, length, level of detail]');
|
|
172
|
+
}
|
|
173
|
+
lines.push('');
|
|
174
|
+
|
|
175
|
+
// ── Level 4: Quality ────────────────────────────────────────────────────
|
|
176
|
+
lines.push('## Output examples');
|
|
177
|
+
lines.push('[3+ real examples of what good output looks like — input → output pairs]');
|
|
178
|
+
lines.push('');
|
|
179
|
+
lines.push('### Example 1');
|
|
180
|
+
lines.push('**Input:** [description]');
|
|
181
|
+
lines.push('**Output:** [what the agent produces]');
|
|
182
|
+
lines.push('');
|
|
183
|
+
lines.push('### Example 2');
|
|
184
|
+
lines.push('**Input:** [description]');
|
|
185
|
+
lines.push('**Output:** [what the agent produces]');
|
|
186
|
+
lines.push('');
|
|
187
|
+
lines.push('### Example 3');
|
|
188
|
+
lines.push('**Input:** [description]');
|
|
189
|
+
lines.push('**Output:** [what the agent produces]');
|
|
190
|
+
lines.push('');
|
|
191
|
+
|
|
192
|
+
lines.push('## Anti-patterns');
|
|
193
|
+
lines.push('');
|
|
194
|
+
lines.push('**Never do:**');
|
|
195
|
+
lines.push('- [Specific mistake this agent must avoid]');
|
|
196
|
+
lines.push('- [Common trap in this domain]');
|
|
197
|
+
lines.push('- [What makes output from this domain feel generic or weak]');
|
|
198
|
+
lines.push('- [Bad habit that would break the agent\'s credibility]');
|
|
199
|
+
lines.push('- [Shortcut that compromises quality]');
|
|
200
|
+
lines.push('');
|
|
201
|
+
lines.push('**Always do:**');
|
|
202
|
+
lines.push('- [Non-negotiable quality behavior]');
|
|
203
|
+
lines.push('- [What distinguishes expert-level output in this domain]');
|
|
204
|
+
lines.push('- [Checkpoint the agent must hit every time]');
|
|
205
|
+
lines.push('- [Structural requirement for every output]');
|
|
206
|
+
lines.push('- [Validation the agent must run before delivering]');
|
|
207
|
+
lines.push('');
|
|
208
|
+
|
|
209
|
+
lines.push('## Completion criteria');
|
|
210
|
+
lines.push('[How to know the work is done — measurable, not subjective]');
|
|
211
|
+
lines.push('- [ ] [Criterion 1]');
|
|
212
|
+
lines.push('- [ ] [Criterion 2]');
|
|
213
|
+
lines.push('- [ ] [Criterion 3]');
|
|
214
|
+
lines.push('');
|
|
215
|
+
|
|
216
|
+
// ── Hard constraints ────────────────────────────────────────────────────
|
|
217
|
+
lines.push('## Hard constraints');
|
|
218
|
+
lines.push('- Use `conversation_language` from project context for all interaction');
|
|
219
|
+
lines.push('- Do not invent facts or requirements — ask when uncertain');
|
|
220
|
+
if (scope === 'squad' && squadSlug) {
|
|
221
|
+
lines.push(`- Stay within squad scope: ${squadSlug}`);
|
|
222
|
+
lines.push(`- Store outputs in the squad directory unless instructed otherwise`);
|
|
223
|
+
}
|
|
224
|
+
if (type === 'worker') {
|
|
225
|
+
lines.push('- Execute deterministically — no creative interpretation of instructions');
|
|
226
|
+
}
|
|
227
|
+
lines.push('');
|
|
228
|
+
|
|
229
|
+
// ── Level 5: Integration ────────────────────────────────────────────────
|
|
230
|
+
lines.push('## Output contract');
|
|
231
|
+
lines.push('[Define what artifacts this agent produces and where they go]');
|
|
232
|
+
lines.push('');
|
|
233
|
+
if (scope === 'squad' && squadSlug) {
|
|
234
|
+
lines.push(`| Artifact | Location | Format |`);
|
|
235
|
+
lines.push(`|----------|----------|--------|`);
|
|
236
|
+
lines.push(`| [Primary output] | \`.aioson/squads/${squadSlug}/[path]\` | [format] |`);
|
|
237
|
+
} else {
|
|
238
|
+
lines.push('| Artifact | Location | Format |');
|
|
239
|
+
lines.push('|----------|----------|--------|');
|
|
240
|
+
lines.push('| [Primary output] | [path] | [format] |');
|
|
241
|
+
}
|
|
242
|
+
lines.push('');
|
|
243
|
+
|
|
244
|
+
lines.push('## Hand-off');
|
|
245
|
+
lines.push('[When this agent finishes, who should run next and with what context?]');
|
|
246
|
+
lines.push('');
|
|
247
|
+
lines.push('| Condition | Next agent | Context to pass |');
|
|
248
|
+
lines.push('|-----------|------------|-----------------|');
|
|
249
|
+
lines.push('| [When X is complete] | [@next-agent] | [What they need to know] |');
|
|
250
|
+
lines.push('| [When review is needed] | [@reviewer or human] | [What to review] |');
|
|
251
|
+
lines.push('');
|
|
252
|
+
|
|
253
|
+
// ── Level 0: Infrastructure (at the end for easy editing) ───────────────
|
|
254
|
+
if (withInfra && scope === 'squad' && squadSlug) {
|
|
255
|
+
lines.push('## Dependencies');
|
|
256
|
+
lines.push('');
|
|
257
|
+
lines.push('```yaml');
|
|
258
|
+
lines.push('skills: []');
|
|
259
|
+
lines.push('tasks:');
|
|
260
|
+
lines.push(` - .aioson/squads/${squadSlug}/tasks/${slug}-main-workflow.md`);
|
|
261
|
+
lines.push('templates:');
|
|
262
|
+
lines.push(` - .aioson/squads/${squadSlug}/templates/${slug}-output-tmpl.md`);
|
|
263
|
+
lines.push('checklists:');
|
|
264
|
+
lines.push(` - .aioson/squads/${squadSlug}/checklists/${slug}-quality-gate.md`);
|
|
265
|
+
lines.push('```');
|
|
266
|
+
lines.push('');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return lines.join('\n');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Operational infrastructure stubs — tasks, templates, checklists
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
|
|
276
|
+
function buildTaskStub(slug, squadSlug) {
|
|
277
|
+
return `# Task: ${slug} main workflow
|
|
278
|
+
|
|
279
|
+
**Task ID:** ${slug}-main
|
|
280
|
+
**Version:** 1.0
|
|
281
|
+
**Purpose:** [What this task accomplishes]
|
|
282
|
+
**Agent:** @${slug}
|
|
283
|
+
**Mode:** Sequential
|
|
284
|
+
|
|
285
|
+
## Inputs
|
|
286
|
+
|
|
287
|
+
| Parameter | Type | Required | Description |
|
|
288
|
+
|-----------|------|----------|-------------|
|
|
289
|
+
| [input_1] | string | Yes | [What this input is] |
|
|
290
|
+
|
|
291
|
+
## Steps
|
|
292
|
+
|
|
293
|
+
### Step 1: Understand context
|
|
294
|
+
**Action:** Read inputs and identify constraints
|
|
295
|
+
**Output:** [What this step produces]
|
|
296
|
+
|
|
297
|
+
### Step 2: Execute
|
|
298
|
+
**Action:** [The core work]
|
|
299
|
+
**Output:** [What this step produces]
|
|
300
|
+
|
|
301
|
+
### Step 3: Validate
|
|
302
|
+
**Action:** Run against completion criteria
|
|
303
|
+
**Output:** Validated deliverable
|
|
304
|
+
|
|
305
|
+
## Veto conditions
|
|
306
|
+
- [ ] [Condition that blocks completion] → STOP and report
|
|
307
|
+
- [ ] [Quality threshold not met] → Return to Step 2
|
|
308
|
+
|
|
309
|
+
## Completion criteria
|
|
310
|
+
- [ ] [Criterion 1]
|
|
311
|
+
- [ ] [Criterion 2]
|
|
312
|
+
`;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function buildTemplateStub(slug) {
|
|
316
|
+
return `# Template: ${slug} output
|
|
317
|
+
|
|
318
|
+
**Version:** 1.0
|
|
319
|
+
|
|
320
|
+
## {Title}
|
|
321
|
+
|
|
322
|
+
**Date:** {date}
|
|
323
|
+
**Agent:** @${slug}
|
|
324
|
+
|
|
325
|
+
### Summary
|
|
326
|
+
{1-3 sentence executive summary}
|
|
327
|
+
|
|
328
|
+
### Content
|
|
329
|
+
{Main structured output}
|
|
330
|
+
|
|
331
|
+
### Recommendations
|
|
332
|
+
{Actionable next steps}
|
|
333
|
+
`;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function buildChecklistStub(slug) {
|
|
337
|
+
return `# Quality gate: @${slug}
|
|
338
|
+
|
|
339
|
+
**Version:** 1.0
|
|
340
|
+
|
|
341
|
+
## Blocking (all must pass)
|
|
342
|
+
- [ ] Output follows the defined template structure
|
|
343
|
+
- [ ] No invented facts — all claims are traceable to input or research
|
|
344
|
+
- [ ] Completion criteria from the agent definition are satisfied
|
|
345
|
+
|
|
346
|
+
## Recommended (80%+ should pass)
|
|
347
|
+
- [ ] Output is concise — no filler or repetition
|
|
348
|
+
- [ ] Domain-specific vocabulary is used correctly
|
|
349
|
+
- [ ] Hand-off context is clear for the next agent
|
|
350
|
+
- [ ] Anti-patterns from the agent definition are avoided
|
|
351
|
+
|
|
352
|
+
## Approval
|
|
353
|
+
- 100% blocking + 80% recommended = **PASS**
|
|
354
|
+
- Any blocking failure = **VETO** — fix before delivering
|
|
355
|
+
`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ---------------------------------------------------------------------------
|
|
359
|
+
// Registration helpers
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
|
|
362
|
+
async function listSquads(projectDir) {
|
|
363
|
+
const squadsDir = path.join(projectDir, SQUADS_DIR);
|
|
364
|
+
if (!(await exists(squadsDir))) return [];
|
|
365
|
+
|
|
366
|
+
const entries = await fs.readdir(squadsDir, { withFileTypes: true });
|
|
367
|
+
const squads = [];
|
|
368
|
+
for (const entry of entries) {
|
|
369
|
+
if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
|
|
370
|
+
const manifestPath = path.join(squadsDir, entry.name, 'squad.manifest.json');
|
|
371
|
+
if (await exists(manifestPath)) {
|
|
372
|
+
try {
|
|
373
|
+
const raw = await fs.readFile(manifestPath, 'utf8');
|
|
374
|
+
const manifest = JSON.parse(raw);
|
|
375
|
+
squads.push({ slug: entry.name, name: manifest.name || entry.name });
|
|
376
|
+
} catch {
|
|
377
|
+
squads.push({ slug: entry.name, name: entry.name });
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return squads;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async function registerInClaudeMd(projectDir, slug, agentPath, scope) {
|
|
385
|
+
const claudeMdPath = path.join(projectDir, 'CLAUDE.md');
|
|
386
|
+
if (!(await exists(claudeMdPath))) return false;
|
|
387
|
+
|
|
388
|
+
let content = await fs.readFile(claudeMdPath, 'utf8');
|
|
389
|
+
|
|
390
|
+
if (scope === 'my-agents') {
|
|
391
|
+
const sectionHeader = '## My agents';
|
|
392
|
+
const entry = `- /${slug} -> \`${agentPath}\``;
|
|
393
|
+
|
|
394
|
+
if (content.includes(sectionHeader)) {
|
|
395
|
+
if (content.includes(entry)) return false;
|
|
396
|
+
content = content.replace(sectionHeader, `${sectionHeader}\n${entry}`);
|
|
397
|
+
} else {
|
|
398
|
+
const agentsSection = content.indexOf('## Agents');
|
|
399
|
+
if (agentsSection !== -1) {
|
|
400
|
+
const nextSection = content.indexOf('\n## ', agentsSection + 1);
|
|
401
|
+
const insertAt = nextSection !== -1 ? nextSection : content.length;
|
|
402
|
+
const block = `\n${sectionHeader}\n${entry}\n`;
|
|
403
|
+
content = content.slice(0, insertAt) + block + content.slice(insertAt);
|
|
404
|
+
} else {
|
|
405
|
+
content += `\n${sectionHeader}\n${entry}\n`;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
const entry = `- /${slug} -> \`${agentPath}\``;
|
|
410
|
+
if (content.includes(entry)) return false;
|
|
411
|
+
content += `\n${entry}\n`;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
await fs.writeFile(claudeMdPath, content, 'utf8');
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
async function registerInAgentsMd(projectDir, slug, agentPath, scope) {
|
|
419
|
+
const agentsMdPath = path.join(projectDir, 'AGENTS.md');
|
|
420
|
+
if (!(await exists(agentsMdPath))) return false;
|
|
421
|
+
|
|
422
|
+
let content = await fs.readFile(agentsMdPath, 'utf8');
|
|
423
|
+
|
|
424
|
+
if (scope === 'my-agents') {
|
|
425
|
+
const sectionHeader = '## My agents';
|
|
426
|
+
const entry = `- @${slug} → \`${agentPath}\``;
|
|
427
|
+
|
|
428
|
+
if (content.includes(sectionHeader)) {
|
|
429
|
+
if (content.includes(`@${slug}`)) return false;
|
|
430
|
+
content = content.replace(sectionHeader, `${sectionHeader}\n${entry}`);
|
|
431
|
+
} else {
|
|
432
|
+
const agentFilesSection = content.indexOf('## Agent files');
|
|
433
|
+
if (agentFilesSection !== -1) {
|
|
434
|
+
const nextSection = content.indexOf('\n## ', agentFilesSection + 1);
|
|
435
|
+
const insertAt = nextSection !== -1 ? nextSection : content.length;
|
|
436
|
+
const block = `\n${sectionHeader}\n${entry}\n`;
|
|
437
|
+
content = content.slice(0, insertAt) + block + content.slice(insertAt);
|
|
438
|
+
} else {
|
|
439
|
+
content += `\n${sectionHeader}\n${entry}\n`;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
} else {
|
|
443
|
+
const entry = `- @${slug} → \`${agentPath}\``;
|
|
444
|
+
if (content.includes(`@${slug}`)) return false;
|
|
445
|
+
content += `\n${entry}\n`;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
await fs.writeFile(agentsMdPath, content, 'utf8');
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ---------------------------------------------------------------------------
|
|
453
|
+
// Main command
|
|
454
|
+
// ---------------------------------------------------------------------------
|
|
455
|
+
|
|
456
|
+
async function runSquadAgentCreate({ args = [], options = {}, logger = console, t } = {}) {
|
|
457
|
+
const projectDir = resolveTargetDir(args);
|
|
458
|
+
const name = options.name || args[1];
|
|
459
|
+
const scope = options.scope || null;
|
|
460
|
+
const squadSlug = options.squad || null;
|
|
461
|
+
const mission = options.mission || null;
|
|
462
|
+
const focus = options.focus ? options.focus.split(',').map(f => f.trim()) : [];
|
|
463
|
+
const type = options.type || 'agent';
|
|
464
|
+
const tier = options.tier || null;
|
|
465
|
+
const disc = options.disc || null;
|
|
466
|
+
const domain = options.domain || null;
|
|
467
|
+
const specialist = options.specialist || null;
|
|
468
|
+
const withInfra = !!options['with-infra'];
|
|
469
|
+
const dryRun = !!options['dry-run'];
|
|
470
|
+
|
|
471
|
+
// Validate name
|
|
472
|
+
if (!name) {
|
|
473
|
+
const msg = t ? t('cli.squad_agent_create.no_name') : 'Usage: aioson squad:agent-create [path] --name=<agent-name> [--scope=my-agents|squad] [--squad=<slug>] [--type=agent|assistant|clone|worker]';
|
|
474
|
+
logger.error(msg);
|
|
475
|
+
return { ok: false, error: 'no_name' };
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const slug = slugify(name);
|
|
479
|
+
|
|
480
|
+
// Validate type
|
|
481
|
+
if (!VALID_TYPES.includes(type)) {
|
|
482
|
+
const msg = t ? t('cli.squad_agent_create.invalid_type', { type }) : `Invalid type: "${type}". Use: ${VALID_TYPES.join(', ')}`;
|
|
483
|
+
logger.error(msg);
|
|
484
|
+
return { ok: false, error: 'invalid_type' };
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Validate tier
|
|
488
|
+
if (tier && !VALID_TIERS.includes(tier)) {
|
|
489
|
+
const msg = t ? t('cli.squad_agent_create.invalid_tier', { tier }) : `Invalid tier: "${tier}". Use: 0 (foundation), 1 (master), 2 (systematizer), 3 (specialist)`;
|
|
490
|
+
logger.error(msg);
|
|
491
|
+
return { ok: false, error: 'invalid_tier' };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Validate DISC
|
|
495
|
+
if (disc && !VALID_DISC.includes(disc)) {
|
|
496
|
+
const msg = t ? t('cli.squad_agent_create.invalid_disc', { disc }) : `Invalid DISC profile: "${disc}". Valid: ${VALID_DISC.join(', ')}`;
|
|
497
|
+
logger.error(msg);
|
|
498
|
+
return { ok: false, error: 'invalid_disc' };
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Determine scope
|
|
502
|
+
let resolvedScope = scope;
|
|
503
|
+
if (!resolvedScope) {
|
|
504
|
+
resolvedScope = squadSlug ? 'squad' : 'my-agents';
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (resolvedScope !== 'my-agents' && resolvedScope !== 'squad') {
|
|
508
|
+
const msg = t ? t('cli.squad_agent_create.invalid_scope', { scope: resolvedScope }) : `Invalid scope: "${resolvedScope}". Use "my-agents" or "squad".`;
|
|
509
|
+
logger.error(msg);
|
|
510
|
+
return { ok: false, error: 'invalid_scope' };
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// If scope=squad, validate squad exists
|
|
514
|
+
let squadName = null;
|
|
515
|
+
if (resolvedScope === 'squad') {
|
|
516
|
+
if (!squadSlug) {
|
|
517
|
+
const squads = await listSquads(projectDir);
|
|
518
|
+
if (squads.length === 0) {
|
|
519
|
+
const msg = t ? t('cli.squad_agent_create.no_squads') : 'No squads found. Create a squad first with @squad or provide --squad=<slug>.';
|
|
520
|
+
logger.error(msg);
|
|
521
|
+
return { ok: false, error: 'no_squads' };
|
|
522
|
+
}
|
|
523
|
+
const msg = t ? t('cli.squad_agent_create.squad_required') : `--squad=<slug> required. Available squads: ${squads.map(s => s.slug).join(', ')}`;
|
|
524
|
+
logger.error(msg);
|
|
525
|
+
return { ok: false, error: 'squad_required', squads: squads.map(s => s.slug) };
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
const squadDir = path.join(projectDir, SQUADS_DIR, squadSlug);
|
|
529
|
+
if (!(await exists(squadDir))) {
|
|
530
|
+
const msg = t ? t('cli.squad_agent_create.squad_not_found', { squad: squadSlug }) : `Squad "${squadSlug}" not found at ${squadDir}`;
|
|
531
|
+
logger.error(msg);
|
|
532
|
+
return { ok: false, error: 'squad_not_found' };
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const manifestPath = path.join(squadDir, 'squad.manifest.json');
|
|
536
|
+
if (await exists(manifestPath)) {
|
|
537
|
+
try {
|
|
538
|
+
const raw = await fs.readFile(manifestPath, 'utf8');
|
|
539
|
+
const manifest = JSON.parse(raw);
|
|
540
|
+
squadName = manifest.name || squadSlug;
|
|
541
|
+
} catch { squadName = squadSlug; }
|
|
542
|
+
} else {
|
|
543
|
+
squadName = squadSlug;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Determine output paths
|
|
548
|
+
let agentRelPath;
|
|
549
|
+
let agentAbsPath;
|
|
550
|
+
if (resolvedScope === 'my-agents') {
|
|
551
|
+
agentRelPath = `${MY_AGENTS_DIR}/${slug}.md`;
|
|
552
|
+
agentAbsPath = path.join(projectDir, agentRelPath);
|
|
553
|
+
} else {
|
|
554
|
+
agentRelPath = `${SQUADS_DIR}/${squadSlug}/agents/${slug}.md`;
|
|
555
|
+
agentAbsPath = path.join(projectDir, agentRelPath);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Check if already exists
|
|
559
|
+
if (await exists(agentAbsPath)) {
|
|
560
|
+
const msg = t ? t('cli.squad_agent_create.already_exists', { path: agentRelPath }) : `Agent already exists: ${agentRelPath}`;
|
|
561
|
+
logger.error(msg);
|
|
562
|
+
return { ok: false, error: 'already_exists', path: agentRelPath };
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Build agent template
|
|
566
|
+
const content = buildAgentTemplate(slug, {
|
|
567
|
+
mission, focus, scope: resolvedScope,
|
|
568
|
+
squadSlug, squadName, type, tier, disc, domain, specialist,
|
|
569
|
+
withInfra
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
if (dryRun) {
|
|
573
|
+
logger.log('');
|
|
574
|
+
logger.log(`[dry-run] Would create: ${agentRelPath}`);
|
|
575
|
+
logger.log(`[dry-run] Scope: ${resolvedScope} | Type: ${type}${tier ? ` | Tier: ${tier}` : ''}`);
|
|
576
|
+
if (resolvedScope === 'squad') logger.log(`[dry-run] Squad: ${squadSlug}`);
|
|
577
|
+
if (withInfra) logger.log('[dry-run] Would generate operational infrastructure stubs');
|
|
578
|
+
logger.log('');
|
|
579
|
+
logger.log(content);
|
|
580
|
+
return { ok: true, dryRun: true, path: agentRelPath, scope: resolvedScope, slug, type };
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Write agent file
|
|
584
|
+
await ensureDir(path.dirname(agentAbsPath));
|
|
585
|
+
await fs.writeFile(agentAbsPath, content, 'utf8');
|
|
586
|
+
|
|
587
|
+
// Generate operational infrastructure stubs (squad scope + --with-infra)
|
|
588
|
+
const infraFiles = [];
|
|
589
|
+
if (withInfra && resolvedScope === 'squad') {
|
|
590
|
+
const tasksDir = path.join(projectDir, SQUADS_DIR, squadSlug, 'tasks');
|
|
591
|
+
const templatesDir = path.join(projectDir, SQUADS_DIR, squadSlug, 'templates');
|
|
592
|
+
const checklistsDir = path.join(projectDir, SQUADS_DIR, squadSlug, 'checklists');
|
|
593
|
+
|
|
594
|
+
const taskPath = path.join(tasksDir, `${slug}-main-workflow.md`);
|
|
595
|
+
const templatePath = path.join(templatesDir, `${slug}-output-tmpl.md`);
|
|
596
|
+
const checklistPath = path.join(checklistsDir, `${slug}-quality-gate.md`);
|
|
597
|
+
|
|
598
|
+
await ensureDir(tasksDir);
|
|
599
|
+
await ensureDir(templatesDir);
|
|
600
|
+
await ensureDir(checklistsDir);
|
|
601
|
+
|
|
602
|
+
if (!(await exists(taskPath))) {
|
|
603
|
+
await fs.writeFile(taskPath, buildTaskStub(slug, squadSlug), 'utf8');
|
|
604
|
+
infraFiles.push(`tasks/${slug}-main-workflow.md`);
|
|
605
|
+
}
|
|
606
|
+
if (!(await exists(templatePath))) {
|
|
607
|
+
await fs.writeFile(templatePath, buildTemplateStub(slug), 'utf8');
|
|
608
|
+
infraFiles.push(`templates/${slug}-output-tmpl.md`);
|
|
609
|
+
}
|
|
610
|
+
if (!(await exists(checklistPath))) {
|
|
611
|
+
await fs.writeFile(checklistPath, buildChecklistStub(slug), 'utf8');
|
|
612
|
+
infraFiles.push(`checklists/${slug}-quality-gate.md`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// Register in CLAUDE.md and AGENTS.md
|
|
617
|
+
const registeredClaude = await registerInClaudeMd(projectDir, slug, agentRelPath, resolvedScope);
|
|
618
|
+
const registeredAgents = await registerInAgentsMd(projectDir, slug, agentRelPath, resolvedScope);
|
|
619
|
+
|
|
620
|
+
// Update squad manifest if scope=squad
|
|
621
|
+
let manifestUpdated = false;
|
|
622
|
+
if (resolvedScope === 'squad') {
|
|
623
|
+
const manifestPath = path.join(projectDir, SQUADS_DIR, squadSlug, 'squad.manifest.json');
|
|
624
|
+
if (await exists(manifestPath)) {
|
|
625
|
+
try {
|
|
626
|
+
const raw = await fs.readFile(manifestPath, 'utf8');
|
|
627
|
+
const manifest = JSON.parse(raw);
|
|
628
|
+
if (!Array.isArray(manifest.executors)) manifest.executors = [];
|
|
629
|
+
|
|
630
|
+
const alreadyExists = manifest.executors.some(e => e.slug === slug);
|
|
631
|
+
if (!alreadyExists) {
|
|
632
|
+
manifest.executors.push({
|
|
633
|
+
slug,
|
|
634
|
+
type,
|
|
635
|
+
role: slug,
|
|
636
|
+
file: agentRelPath,
|
|
637
|
+
tier: tier ? Number(tier) : undefined,
|
|
638
|
+
disc: disc || undefined,
|
|
639
|
+
skills: [],
|
|
640
|
+
genomes: []
|
|
641
|
+
});
|
|
642
|
+
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
643
|
+
manifestUpdated = true;
|
|
644
|
+
}
|
|
645
|
+
} catch { /* manifest parse error — skip */ }
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Output
|
|
650
|
+
logger.log('');
|
|
651
|
+
logger.log(` Agent created: ${agentRelPath}`);
|
|
652
|
+
logger.log(` Scope: ${resolvedScope === 'my-agents' ? 'my-agents (versioned, available globally)' : `squad:${squadSlug}`}`);
|
|
653
|
+
logger.log(` Type: ${type}${tier ? ` | Tier: ${tier}` : ''}${disc ? ` | DISC: ${disc}` : ''}`);
|
|
654
|
+
logger.log(` Slug: @${slug}`);
|
|
655
|
+
if (registeredClaude) logger.log(' Registered in CLAUDE.md');
|
|
656
|
+
if (registeredAgents) logger.log(' Registered in AGENTS.md');
|
|
657
|
+
if (manifestUpdated) logger.log(` Added to squad manifest: ${squadSlug}`);
|
|
658
|
+
if (infraFiles.length > 0) {
|
|
659
|
+
logger.log(` Infrastructure stubs: ${infraFiles.join(', ')}`);
|
|
660
|
+
}
|
|
661
|
+
logger.log('');
|
|
662
|
+
|
|
663
|
+
// Maturity assessment
|
|
664
|
+
const maturity = assessMaturity(content, infraFiles.length > 0);
|
|
665
|
+
logger.log(` Maturity: Level ${maturity.level} — ${maturity.label} (${maturity.score}/10)`);
|
|
666
|
+
logger.log(` ${maturity.hint}`);
|
|
667
|
+
logger.log('');
|
|
668
|
+
|
|
669
|
+
logger.log(' Next steps:');
|
|
670
|
+
logger.log(` 1. Fill in [bracketed placeholders] in ${agentRelPath}`);
|
|
671
|
+
logger.log(' 2. Add real output examples (input → output pairs)');
|
|
672
|
+
logger.log(' 3. Define anti-patterns specific to this agent\'s domain');
|
|
673
|
+
if (type === 'assistant' || type === 'clone') {
|
|
674
|
+
logger.log(' 4. Complete the Voice DNA section with real vocabulary and sentence starters');
|
|
675
|
+
}
|
|
676
|
+
logger.log(` ${type === 'assistant' || type === 'clone' ? '5' : '4'}. Invoke with @${slug} in your AI session`);
|
|
677
|
+
if (resolvedScope === 'my-agents') {
|
|
678
|
+
logger.log(` ${type === 'assistant' || type === 'clone' ? '6' : '5'}. This agent is versioned with the project — commit to share with the team`);
|
|
679
|
+
}
|
|
680
|
+
logger.log('');
|
|
681
|
+
|
|
682
|
+
return {
|
|
683
|
+
ok: true,
|
|
684
|
+
path: agentRelPath,
|
|
685
|
+
scope: resolvedScope,
|
|
686
|
+
slug,
|
|
687
|
+
type,
|
|
688
|
+
tier: tier ? Number(tier) : null,
|
|
689
|
+
disc,
|
|
690
|
+
squad: squadSlug,
|
|
691
|
+
registeredClaude,
|
|
692
|
+
registeredAgents,
|
|
693
|
+
manifestUpdated,
|
|
694
|
+
infraFiles,
|
|
695
|
+
maturity
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// ---------------------------------------------------------------------------
|
|
700
|
+
// Maturity scoring — adapted from AIOX maturity levels
|
|
701
|
+
// ---------------------------------------------------------------------------
|
|
702
|
+
|
|
703
|
+
function assessMaturity(content, hasInfra) {
|
|
704
|
+
let score = 0;
|
|
705
|
+
const checks = [];
|
|
706
|
+
|
|
707
|
+
// Identity (1.0)
|
|
708
|
+
if (content.includes('## Mission') && !content.includes('[Define the agent mission')) {
|
|
709
|
+
score += 1.0; checks.push('identity');
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// Core principles (1.0)
|
|
713
|
+
if (content.includes('## Core principles') && !content.includes('[5-10 fundamental')) {
|
|
714
|
+
score += 1.0; checks.push('principles');
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Operational framework (1.0)
|
|
718
|
+
if (content.includes('## Operational framework')) {
|
|
719
|
+
score += 0.5; checks.push('framework-stub');
|
|
720
|
+
if (!content.includes('[Step-by-step methodology')) {
|
|
721
|
+
score += 0.5; checks.push('framework-filled');
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Voice DNA (1.5 — for types that have it)
|
|
726
|
+
if (content.includes('## Voice DNA')) {
|
|
727
|
+
score += 0.5; checks.push('voice-stub');
|
|
728
|
+
if (!content.includes('[How this agent opens')) {
|
|
729
|
+
score += 1.0; checks.push('voice-filled');
|
|
730
|
+
}
|
|
731
|
+
} else {
|
|
732
|
+
// Types without voice DNA get the points automatically
|
|
733
|
+
score += 1.5; checks.push('voice-na');
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Output examples (1.5)
|
|
737
|
+
if (content.includes('## Output examples')) {
|
|
738
|
+
score += 0.5; checks.push('examples-stub');
|
|
739
|
+
const exampleBlocks = (content.match(/\*\*Input:\*\*/g) || []).length;
|
|
740
|
+
if (exampleBlocks >= 3) {
|
|
741
|
+
score += 1.0; checks.push('examples-filled');
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// Anti-patterns (1.0)
|
|
746
|
+
if (content.includes('## Anti-patterns')) {
|
|
747
|
+
score += 0.5; checks.push('anti-stub');
|
|
748
|
+
if (!content.includes('[Specific mistake')) {
|
|
749
|
+
score += 0.5; checks.push('anti-filled');
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Completion criteria (0.5)
|
|
754
|
+
if (content.includes('## Completion criteria') && !content.includes('[Criterion 1]')) {
|
|
755
|
+
score += 0.5; checks.push('criteria');
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Hand-off (0.5)
|
|
759
|
+
if (content.includes('## Hand-off') && !content.includes('[@next-agent]')) {
|
|
760
|
+
score += 0.5; checks.push('handoff');
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// Infrastructure (1.5)
|
|
764
|
+
if (hasInfra) {
|
|
765
|
+
score += 1.5; checks.push('infra');
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
score = Math.min(10, Math.round(score * 10) / 10);
|
|
769
|
+
|
|
770
|
+
let level, label, hint;
|
|
771
|
+
if (score < 4) {
|
|
772
|
+
level = 1; label = 'Persona only (scaffold)';
|
|
773
|
+
hint = 'Fill in mission, principles, examples, and anti-patterns to reach Level 2.';
|
|
774
|
+
} else if (score < 7) {
|
|
775
|
+
level = 2; label = 'Functional (needs enrichment)';
|
|
776
|
+
hint = 'Add real output examples and domain-specific anti-patterns to reach Level 3.';
|
|
777
|
+
} else if (score < 9) {
|
|
778
|
+
level = 3; label = 'Operational (deterministic)';
|
|
779
|
+
hint = 'Agent is ready for use. Consider adding --with-infra for full operational files.';
|
|
780
|
+
} else {
|
|
781
|
+
level = 3; label = 'Production-ready';
|
|
782
|
+
hint = 'Agent is complete with operational infrastructure. Ready for production.';
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return { score, level, label, hint, checks };
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
module.exports = { runSquadAgentCreate };
|