claude-flow-novice 2.15.11 → 2.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/cfn-extras/agents/cfn-v3-coordinator.md +517 -0
- package/.claude/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +1 -1
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +1 -1
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +1 -1
- package/.claude/cfn-extras/skills/google-sheets-progress/SKILL.md +1 -1
- package/.claude/commands/CFN_LOOP_FRONTEND.md +1 -1
- package/.claude/commands/cfn-loop-cli.md +214 -442
- package/.claude/commands/cfn-loop-frontend.md +1 -1
- package/.claude/commands/cfn-loop-task.md +2 -2
- package/.claude/commands/cfn-loop-trigger.md +114 -0
- package/.claude/commands/deprecated/cfn-loop.md +2 -2
- package/.claude/hooks/cfn-invoke-post-edit-ts.sh +100 -0
- package/.claude/hooks/cfn-invoke-post-edit-ts.sh.backup +78 -0
- package/.claude/hooks/cfn-invoke-post-edit.sh +53 -5
- package/.claude/hooks/cfn-invoke-post-edit.sh.backup +87 -0
- package/.claude/hooks/cfn-invoke-pre-edit-ts.sh +116 -0
- package/.claude/hooks/cfn-invoke-pre-edit-ts.sh.backup +94 -0
- package/.claude/hooks/cfn-invoke-pre-edit.sh +22 -0
- package/.claude/hooks/cfn-invoke-pre-edit.sh.backup +88 -0
- package/.claude/hooks/cfn-post-edit.config.json +9 -2
- package/.claude/root-claude-distribute/CFN-CLAUDE.md +1 -1
- package/.claude/skills/cfn-agent-spawning/SKILL.md +48 -1
- package/.claude/skills/cfn-agent-spawning/SKILL.md.backup +135 -0
- package/.claude/skills/cfn-agent-spawning/TYPESCRIPT_MIGRATION.md +567 -0
- package/.claude/skills/cfn-agent-spawning/check-dependencies.sh +22 -0
- package/.claude/skills/{cfn-redis-coordination/check-dependencies.sh → cfn-agent-spawning/check-dependencies.sh.backup} +3 -5
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh.backup +127 -0
- package/.claude/skills/cfn-agent-spawning/parse-agent-provider.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/parse-agent-provider.sh.backup +59 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent-wrapper.sh +63 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent-wrapper.sh.backup +41 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +26 -1
- package/.claude/skills/cfn-agent-spawning/spawn-templates.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/spawn-templates.sh.backup +613 -0
- package/.claude/skills/cfn-agent-spawning/spawn-worker.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/spawn-worker.sh.backup +176 -0
- package/.claude/skills/cfn-backlog-management/SKILL.md +1 -1
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/metadata.json +8 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/original +271 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/revert.sh +7 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/metadata.json +8 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/original +325 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/revert.sh +7 -0
- package/.claude/skills/cfn-loop-orchestration/CLI_IMPLEMENTATION_SUMMARY.md +330 -0
- package/.claude/skills/cfn-loop-orchestration/CONFIGURATION_IMPROVEMENTS.md +318 -0
- package/.claude/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_MIGRATION.md +308 -0
- package/.claude/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_QUICK_START.md +378 -0
- package/.claude/skills/cfn-loop-orchestration/E2E_VALIDATION_REPORT.md +262 -0
- package/.claude/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +319 -519
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_E2E_REPORT.md +299 -0
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_EXECUTION_SUMMARY.md +403 -0
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +323 -0
- package/.claude/skills/cfn-loop-orchestration/SKILL.md +159 -48
- package/.claude/skills/cfn-loop-orchestration/SPAWN_AGENTS_IMPLEMENTATION.md +188 -0
- package/.claude/skills/cfn-loop-orchestration/TEST_COVERAGE_REPORT.md +335 -0
- package/.claude/skills/cfn-loop-orchestration/TEST_COVERAGE_SUMMARY.md +456 -0
- package/.claude/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_REPORT.md +709 -0
- package/.claude/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_SUMMARY.md +257 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATION_REPORT.md +572 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATION_SUMMARY.txt +196 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATOR_MODULE_GUIDE.md +526 -0
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/README.md +167 -0
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate-enhanced.sh +548 -0
- package/.claude/skills/cfn-loop-orchestration/{orchestrate-wrapper.sh → archive/legacy-bash/orchestrate-wrapper.sh} +11 -1
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate.sh +182 -0
- package/.claude/skills/cfn-loop-orchestration/e2e-validation-fixed.js +240 -0
- package/.claude/skills/cfn-loop-orchestration/e2e-validation.js +213 -0
- package/.claude/skills/cfn-loop-orchestration/package-lock.json +3 -0
- package/.claude/skills/cfn-loop-orchestration/package.json +4 -0
- package/.claude/skills/cfn-loop-orchestration/run-north-star-e2e.ts +210 -0
- package/.claude/skills/cfn-loop-orchestration/src/cli/orchestrator-cli.ts +396 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR.md +564 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR_QUICK_REF.md +241 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_IMPLEMENTATION.md +375 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_QUICK_REFERENCE.md +362 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_README.md +307 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_USAGE_GUIDE.md +508 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts +473 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/consensus.ts +1 -1
- package/.claude/skills/cfn-loop-orchestration/src/helpers/context-injector.ts +349 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/context-lookup.ts +486 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/deliverable-verifier.ts +6 -2
- package/.claude/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +1 -1
- package/.claude/skills/cfn-loop-orchestration/src/helpers/product-owner-decision.ts +316 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/spawn-agents.ts +357 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/validator.ts +276 -0
- package/.claude/skills/cfn-loop-orchestration/src/index.ts +2 -0
- package/.claude/skills/cfn-loop-orchestration/src/orchestrate.ts +743 -2
- package/.claude/skills/cfn-loop-orchestration/src/types.ts +56 -0
- package/.claude/skills/cfn-loop-orchestration/test-cli.sh +92 -0
- package/.claude/skills/cfn-loop-orchestration/test-typescript-integration.sh +442 -0
- package/.claude/skills/cfn-loop-orchestration/tests/agent-spawner.test.ts +124 -0
- package/.claude/skills/cfn-loop-orchestration/tests/confidence-aggregator.test.ts +604 -0
- package/.claude/skills/cfn-loop-orchestration/tests/context-injector.test.ts +561 -0
- package/.claude/skills/cfn-loop-orchestration/tests/context-lookup.test.ts +661 -0
- package/.claude/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +2 -2
- package/.claude/skills/cfn-loop-orchestration/tests/gate-check-edge-cases.test.ts +422 -0
- package/.claude/skills/cfn-loop-orchestration/tests/gate-checker.test.ts +276 -0
- package/.claude/skills/cfn-loop-orchestration/tests/logger.test.ts +291 -0
- package/.claude/skills/cfn-loop-orchestration/tests/north-star-e2e.test.ts +334 -0
- package/.claude/skills/cfn-loop-orchestration/tests/redis-coordinator.test.ts +321 -0
- package/.claude/skills/cfn-loop-orchestration/tests/spawn-agents.test.ts +284 -0
- package/.claude/skills/cfn-loop-orchestration/tests/validator.test.ts +643 -0
- package/.claude/skills/cfn-loop-validation/IMPLEMENTATION_SUMMARY.md +672 -0
- package/.claude/skills/cfn-loop-validation/INDEX.md +531 -0
- package/.claude/skills/cfn-loop-validation/README_TYPESCRIPT.md +454 -0
- package/.claude/skills/cfn-loop-validation/SKILL.md +48 -1
- package/.claude/skills/cfn-loop-validation/SKILL.md.backup +353 -0
- package/.claude/skills/cfn-loop-validation/SKILL_TYPESCRIPT.md +782 -0
- package/.claude/skills/cfn-loop-validation/VAPOR_DETECTION_EXAMPLES.md +598 -0
- package/.claude/skills/cfn-loop-validation/check-dependencies.sh +22 -0
- package/{claude-assets/skills/cfn-redis-coordination/check-dependencies.sh → .claude/skills/cfn-loop-validation/check-dependencies.sh.backup} +4 -5
- package/.claude/skills/cfn-loop-validation/detect-vapor.sh +59 -0
- package/.claude/skills/cfn-loop-validation/detect-vapor.sh.backup +37 -0
- package/.claude/skills/cfn-loop-validation/dist/.tsbuildinfo +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts +14 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.js +185 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts +14 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.js +176 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts +19 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.js +123 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/types.d.ts +156 -0
- package/.claude/skills/cfn-loop-validation/dist/types.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/types.js +66 -0
- package/.claude/skills/cfn-loop-validation/dist/types.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.d.ts +85 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.js +411 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +22 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh.backup +252 -0
- package/.claude/skills/cfn-loop-validation/package.json +93 -0
- package/.claude/skills/cfn-loop-validation/src/cli/detect-vapor.ts +177 -0
- package/.claude/skills/cfn-loop-validation/src/cli/validate-deliverables.ts +161 -0
- package/.claude/skills/cfn-loop-validation/src/cli/validate-gate.ts +139 -0
- package/.claude/skills/cfn-loop-validation/src/types.ts +215 -0
- package/.claude/skills/cfn-loop-validation/src/validator.ts +503 -0
- package/.claude/skills/cfn-loop-validation/tests/validator.test.ts +537 -0
- package/.claude/skills/{cfn-redis-coordination → cfn-loop-validation}/tsconfig.json +34 -31
- package/.claude/skills/cfn-loop-validation/validate-deliverables.sh +59 -0
- package/.claude/skills/cfn-loop-validation/validate-deliverables.sh.backup +37 -0
- package/.claude/skills/cfn-loop-validation/validate-gate.sh +63 -0
- package/.claude/skills/cfn-loop-validation/validate-gate.sh.backup +41 -0
- package/.claude/skills/cfn-loop-validation/validate-iteration.sh +22 -0
- package/.claude/skills/cfn-loop-validation/validate-iteration.sh.backup +134 -0
- package/.claude/skills/cfn-product-owner-decision/SKILL.md +479 -147
- package/.claude/skills/cfn-product-owner-decision/TYPESCRIPT_IMPLEMENTATION.md +653 -0
- package/.claude/skills/cfn-product-owner-decision/{execute-decision.sh → archive/legacy-bash/execute-decision.sh} +24 -2
- package/.claude/skills/pre-edit-backup/SKILL.md +324 -0
- package/.claude/skills/pre-edit-backup/SKILL.md.backup +277 -0
- package/.claude/skills/pre-edit-backup/backup.sh +22 -0
- package/.claude/skills/pre-edit-backup/backup.sh.backup +107 -0
- package/claude-assets/agents/cfn-dev-team/analysts/root-cause-analyst.md +2 -2
- package/claude-assets/agents/cfn-dev-team/architecture/base-template-generator.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +3 -2
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +2 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +11 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +58 -35
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +2 -2
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +47 -37
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +18 -18
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +40 -58
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +19 -21
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +20 -29
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +15 -19
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +15 -10
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +16 -11
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +16 -26
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +18 -22
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +17 -21
- package/claude-assets/agents/cfn-dev-team/documentation/pseudocode.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/cto-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/power-user-persona.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/product-owner.md +1 -5
- package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +20 -51
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +22 -71
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +21 -64
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +22 -67
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +24 -68
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +8 -36
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +9 -38
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +17 -55
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +18 -56
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +9 -37
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +18 -56
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +18 -49
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +8 -37
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +7 -27
- package/claude-assets/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/agent-builder.md +11 -0
- package/claude-assets/agents/cfn-dev-team/utility/analyst.md +13 -29
- package/claude-assets/agents/cfn-dev-team/utility/claude-code-expert.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +13 -13
- package/claude-assets/agents/cfn-dev-team/utility/context-curator.md +7 -2
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +6 -11
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +121 -715
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +13 -22
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +147 -573
- package/claude-assets/agents/custom/cfn-docker-expert.md +103 -0
- package/claude-assets/agents/custom/cfn-loops-cli-expert.md +438 -0
- package/claude-assets/agents/custom/cfn-redis-operations.md +529 -529
- package/claude-assets/agents/custom/cfn-system-expert.md +1 -1
- package/claude-assets/agents/custom/trigger-dev-expert.md +369 -0
- package/claude-assets/agents/docker-team/micro-sprint-planner.md +747 -747
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/agents/cfn-v3-coordinator.md +517 -0
- package/claude-assets/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +1 -1
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +1 -1
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +1 -1
- package/claude-assets/cfn-extras/skills/google-sheets-progress/SKILL.md +1 -1
- package/claude-assets/commands/CFN_LOOP_FRONTEND.md +1 -1
- package/claude-assets/commands/cfn-loop-cli.md +214 -442
- package/claude-assets/commands/cfn-loop-frontend.md +1 -1
- package/claude-assets/commands/cfn-loop-task.md +2 -2
- package/claude-assets/commands/cfn-loop-trigger.md +114 -0
- package/claude-assets/commands/deprecated/cfn-loop.md +2 -2
- package/claude-assets/hooks/GIT-HOOKS-USAGE-EXAMPLES.md +116 -0
- package/claude-assets/hooks/README-GIT-HOOKS.md +443 -0
- package/claude-assets/hooks/SKILL.md +518 -0
- package/claude-assets/hooks/SKILL.md.backup +471 -0
- package/claude-assets/hooks/cfn-invoke-post-edit-ts.sh +100 -0
- package/claude-assets/hooks/cfn-invoke-post-edit-ts.sh.backup +78 -0
- package/claude-assets/hooks/cfn-invoke-post-edit.sh +53 -5
- package/claude-assets/hooks/cfn-invoke-post-edit.sh.backup +87 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit-ts.sh +116 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit-ts.sh.backup +94 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit.sh +22 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit.sh.backup +88 -0
- package/claude-assets/hooks/cfn-post-edit.config.json +9 -2
- package/claude-assets/hooks/install-git-hooks.sh +243 -0
- package/claude-assets/hooks/subagent-start.sh +98 -0
- package/claude-assets/hooks/subagent-stop.sh +93 -0
- package/claude-assets/hooks/validators/credential-scanner.sh +172 -0
- package/claude-assets/root-claude-distribute/CFN-CLAUDE.md +1 -1
- package/claude-assets/skills/cfn-agent-selection-with-fallback/DELIVERABLES.md +409 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/IMPLEMENTATION_SUMMARY.md +396 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/INTEGRATION_GUIDE.md +308 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/QUICK_REFERENCE.md +239 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md +107 -1
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md.backup +302 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/TYPESCRIPT_MIGRATION.md +295 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/agent-selector.cjs +297 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/agent-selector.js +297 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/cli.cjs +96 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/cli.js +96 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents-ts.sh +45 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents-ts.sh.backup +23 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh +22 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh.backup +173 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/agent-selector.test.ts +357 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/agent-selector.ts +350 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/cli.ts +74 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh +22 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh.backup +71 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/tsconfig.json +18 -0
- package/claude-assets/skills/cfn-agent-spawning/SKILL.md +48 -1
- package/claude-assets/skills/cfn-agent-spawning/SKILL.md.backup +135 -0
- package/claude-assets/skills/cfn-agent-spawning/TYPESCRIPT_MIGRATION.md +567 -0
- package/claude-assets/skills/cfn-agent-spawning/check-dependencies.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/check-dependencies.sh.backup +30 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh.backup +127 -0
- package/claude-assets/skills/cfn-agent-spawning/parse-agent-provider.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/parse-agent-provider.sh.backup +59 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent-wrapper.sh +63 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent-wrapper.sh.backup +41 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +26 -1
- package/claude-assets/skills/cfn-agent-spawning/spawn-templates.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-templates.sh.backup +613 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-worker.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-worker.sh.backup +176 -0
- package/claude-assets/skills/cfn-backlog-management/SKILL.md +1 -1
- package/claude-assets/skills/cfn-coordination/agent-completion.sh.backup +36 -0
- package/claude-assets/skills/cfn-coordination/coordination-signal.sh.backup +36 -0
- package/claude-assets/skills/cfn-coordination/coordination-wait.sh.backup +36 -0
- package/claude-assets/skills/cfn-dependency-ingestion/README.md +101 -0
- package/claude-assets/skills/cfn-dependency-ingestion/SKILL.md +397 -0
- package/claude-assets/skills/cfn-dependency-ingestion/build.sh +23 -0
- package/claude-assets/skills/cfn-dependency-ingestion/dist/ingest-dependencies.js +478 -0
- package/claude-assets/skills/cfn-dependency-ingestion/ingest-dependencies.sh +295 -0
- package/claude-assets/skills/cfn-dependency-ingestion/ingest.sh +237 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/cli-mode-dependencies.txt +73 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/shared-dependencies.txt +57 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/trigger-dev-dependencies.txt +82 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/trigger-mode-dependencies.txt +80 -0
- package/claude-assets/skills/cfn-dependency-ingestion/src/ingest-dependencies.ts +563 -0
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +14 -4
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/metadata.json +8 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/original +271 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/revert.sh +7 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/metadata.json +8 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/original +325 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/revert.sh +7 -0
- package/claude-assets/skills/cfn-loop-orchestration/CLI_IMPLEMENTATION_SUMMARY.md +330 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONFIGURATION_IMPROVEMENTS.md +318 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_MIGRATION.md +308 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_QUICK_START.md +378 -0
- package/claude-assets/skills/cfn-loop-orchestration/E2E_VALIDATION_REPORT.md +262 -0
- package/claude-assets/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +319 -519
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_E2E_REPORT.md +299 -0
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_EXECUTION_SUMMARY.md +403 -0
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +323 -0
- package/claude-assets/skills/cfn-loop-orchestration/SKILL.md +159 -48
- package/claude-assets/skills/cfn-loop-orchestration/SPAWN_AGENTS_IMPLEMENTATION.md +188 -0
- package/claude-assets/skills/cfn-loop-orchestration/TEST_COVERAGE_REPORT.md +335 -0
- package/claude-assets/skills/cfn-loop-orchestration/TEST_COVERAGE_SUMMARY.md +456 -0
- package/claude-assets/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_REPORT.md +709 -0
- package/claude-assets/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_SUMMARY.md +257 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATION_REPORT.md +572 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATION_SUMMARY.txt +196 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATOR_MODULE_GUIDE.md +526 -0
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/README.md +167 -0
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate-enhanced.sh +548 -0
- package/claude-assets/skills/cfn-loop-orchestration/{orchestrate-wrapper.sh → archive/legacy-bash/orchestrate-wrapper.sh} +11 -1
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate.sh +182 -0
- package/claude-assets/skills/cfn-loop-orchestration/e2e-validation-fixed.js +240 -0
- package/claude-assets/skills/cfn-loop-orchestration/e2e-validation.js +213 -0
- package/claude-assets/skills/cfn-loop-orchestration/package-lock.json +3 -0
- package/claude-assets/skills/cfn-loop-orchestration/package.json +4 -0
- package/claude-assets/skills/cfn-loop-orchestration/run-north-star-e2e.ts +210 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/cli/orchestrator-cli.ts +396 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR.md +564 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR_QUICK_REF.md +241 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_IMPLEMENTATION.md +375 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_QUICK_REFERENCE.md +362 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_README.md +307 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_USAGE_GUIDE.md +508 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts +473 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/consensus.ts +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/context-injector.ts +349 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/context-lookup.ts +486 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/deliverable-verifier.ts +6 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/product-owner-decision.ts +316 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/spawn-agents.ts +357 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/validator.ts +276 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/index.ts +2 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/orchestrate.ts +743 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/types.ts +56 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-cli.sh +92 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-typescript-integration.sh +442 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/agent-spawner.test.ts +124 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/confidence-aggregator.test.ts +604 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/context-injector.test.ts +561 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/context-lookup.test.ts +661 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +2 -2
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-check-edge-cases.test.ts +422 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-checker.test.ts +276 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/logger.test.ts +291 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/north-star-e2e.test.ts +334 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/redis-coordinator.test.ts +321 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/spawn-agents.test.ts +284 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/validator.test.ts +643 -0
- package/claude-assets/skills/cfn-loop-output-processing/.eslintrc.json +33 -0
- package/claude-assets/skills/cfn-loop-output-processing/DELIVERY_SUMMARY.txt +462 -0
- package/claude-assets/skills/cfn-loop-output-processing/DEPRECATION_NOTICE.md +183 -0
- package/claude-assets/skills/cfn-loop-output-processing/EXAMPLES.md +609 -0
- package/claude-assets/skills/cfn-loop-output-processing/IMPLEMENTATION_SUMMARY.md +418 -0
- package/claude-assets/skills/cfn-loop-output-processing/INDEX.md +531 -0
- package/claude-assets/skills/cfn-loop-output-processing/MIGRATION.md +362 -0
- package/claude-assets/skills/cfn-loop-output-processing/README.md +114 -0
- package/claude-assets/skills/cfn-loop-output-processing/SKILL.md +633 -0
- package/{.claude/skills/cfn-docker-redis-coordination → claude-assets/skills/cfn-loop-output-processing}/jest.config.js +7 -15
- package/claude-assets/skills/cfn-loop-output-processing/package.json +50 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/cli/process-loop2.ts +195 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/cli/process-loop3.ts +157 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/output-processor.ts +632 -0
- package/claude-assets/skills/cfn-loop-output-processing/tests/output-processor.test.ts +617 -0
- package/claude-assets/skills/{cfn-docker-redis-coordination → cfn-loop-output-processing}/tsconfig.json +16 -7
- package/claude-assets/skills/cfn-loop-validation/IMPLEMENTATION_SUMMARY.md +672 -0
- package/claude-assets/skills/cfn-loop-validation/INDEX.md +531 -0
- package/claude-assets/skills/cfn-loop-validation/README_TYPESCRIPT.md +454 -0
- package/claude-assets/skills/cfn-loop-validation/SKILL.md +48 -1
- package/claude-assets/skills/cfn-loop-validation/SKILL.md.backup +353 -0
- package/claude-assets/skills/cfn-loop-validation/SKILL_TYPESCRIPT.md +782 -0
- package/claude-assets/skills/cfn-loop-validation/VAPOR_DETECTION_EXAMPLES.md +598 -0
- package/claude-assets/skills/cfn-loop-validation/check-dependencies.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/check-dependencies.sh.backup +31 -0
- package/claude-assets/skills/cfn-loop-validation/detect-vapor.sh +59 -0
- package/claude-assets/skills/cfn-loop-validation/detect-vapor.sh.backup +37 -0
- package/claude-assets/skills/cfn-loop-validation/dist/.tsbuildinfo +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts +14 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.js +185 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts +14 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.js +176 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts +19 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.js +123 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.d.ts +156 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.js +66 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.d.ts +85 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.js +411 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh.backup +252 -0
- package/claude-assets/skills/cfn-loop-validation/package.json +93 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/detect-vapor.ts +177 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/validate-deliverables.ts +161 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/validate-gate.ts +139 -0
- package/claude-assets/skills/cfn-loop-validation/src/types.ts +215 -0
- package/claude-assets/skills/cfn-loop-validation/src/validator.ts +503 -0
- package/claude-assets/skills/cfn-loop-validation/tests/validator.test.ts +537 -0
- package/claude-assets/skills/{cfn-redis-coordination → cfn-loop-validation}/tsconfig.json +34 -31
- package/claude-assets/skills/cfn-loop-validation/validate-deliverables.sh +59 -0
- package/claude-assets/skills/cfn-loop-validation/validate-deliverables.sh.backup +37 -0
- package/claude-assets/skills/cfn-loop-validation/validate-gate.sh +63 -0
- package/claude-assets/skills/cfn-loop-validation/validate-gate.sh.backup +41 -0
- package/claude-assets/skills/cfn-loop-validation/validate-iteration.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/validate-iteration.sh.backup +134 -0
- package/claude-assets/skills/cfn-product-owner-decision/SKILL.md +479 -147
- package/claude-assets/skills/cfn-product-owner-decision/TYPESCRIPT_IMPLEMENTATION.md +653 -0
- package/claude-assets/skills/cfn-product-owner-decision/{execute-decision.sh → archive/legacy-bash/execute-decision.sh} +24 -2
- package/claude-assets/skills/cfn-provider-routing/README.md +129 -0
- package/claude-assets/skills/cfn-provider-routing/SKILL.md +215 -0
- package/claude-assets/skills/cfn-provider-routing/resolve-provider-model.ts +223 -0
- package/claude-assets/skills/docker-build/build.sh +1 -1
- package/claude-assets/skills/pre-edit-backup/SKILL.md +324 -0
- package/claude-assets/skills/pre-edit-backup/SKILL.md.backup +277 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh +22 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh.backup +107 -0
- package/dist/agent/skill-mcp-selector.js +2 -1
- package/dist/agent/skill-mcp-selector.js.map +1 -1
- package/dist/api/auth-endpoints.js +415 -0
- package/dist/api/auth-endpoints.js.map +1 -0
- package/dist/api/task-endpoints.js +562 -0
- package/dist/api/task-endpoints.js.map +1 -0
- package/dist/backend/server.js +418 -0
- package/dist/backend/server.js.map +1 -0
- package/dist/cfn-loop/product-owner/decision-parser.js +356 -0
- package/dist/cfn-loop/product-owner/decision-parser.js.map +1 -0
- package/dist/cfn-loop/product-owner/index.js +1 -0
- package/dist/cfn-loop/product-owner/index.js.map +1 -1
- package/dist/cli/agent-command.js +1 -1
- package/dist/cli/agent-command.js.map +1 -1
- package/dist/cli/agent-completion.js +273 -0
- package/dist/cli/agent-completion.js.map +1 -0
- package/dist/cli/agent-executor.js +470 -26
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +83 -48
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +7 -4
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/agent-spawner.js +546 -0
- package/dist/cli/agent-spawner.js.map +1 -0
- package/dist/cli/agent-token-manager.js +2 -1
- package/dist/cli/agent-token-manager.js.map +1 -1
- package/dist/cli/anthropic-client.js +127 -14
- package/dist/cli/anthropic-client.js.map +1 -1
- package/dist/cli/cfn-context.js +2 -1
- package/dist/cli/cfn-context.js.map +1 -1
- package/dist/cli/cfn-metrics.js +2 -1
- package/dist/cli/cfn-metrics.js.map +1 -1
- package/dist/cli/cfn-redis.js +2 -1
- package/dist/cli/cfn-redis.js.map +1 -1
- package/dist/cli/cli-agent-context.js +2 -0
- package/dist/cli/cli-agent-context.js.map +1 -1
- package/dist/cli/config-manager.js +90 -356
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/conversation-fork-cleanup.js +2 -1
- package/dist/cli/conversation-fork-cleanup.js.map +1 -1
- package/dist/cli/conversation-fork.js +2 -1
- package/dist/cli/conversation-fork.js.map +1 -1
- package/dist/cli/coordination/agent-messaging.js +415 -0
- package/dist/cli/coordination/agent-messaging.js.map +1 -0
- package/dist/cli/coordination/wait-for-threshold.js +232 -0
- package/dist/cli/coordination/wait-for-threshold.js.map +1 -0
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/iteration-history.js +2 -1
- package/dist/cli/iteration-history.js.map +1 -1
- package/dist/cli/parse-decision-cli.js +268 -0
- package/dist/cli/parse-decision-cli.js.map +1 -0
- package/dist/cli/post-edit-hook.js +83 -0
- package/dist/cli/post-edit-hook.js.map +1 -0
- package/dist/cli/pre-edit-hook.js +77 -0
- package/dist/cli/pre-edit-hook.js.map +1 -0
- package/dist/cli/process-lifecycle.js +5 -1
- package/dist/cli/process-lifecycle.js.map +1 -1
- package/dist/cli/spawn-agent-cli.js +244 -0
- package/dist/cli/spawn-agent-cli.js.map +1 -0
- package/dist/coordination/coordination-wrapper.js +383 -0
- package/dist/coordination/coordination-wrapper.js.map +1 -0
- package/dist/coordination/redis-waiting-mode.js +4 -0
- package/dist/coordination/redis-waiting-mode.js.map +1 -1
- package/dist/coordination/store-success-criteria.js +68 -0
- package/dist/coordination/store-success-criteria.js.map +1 -0
- package/dist/coordination/store-task-context.js +65 -0
- package/dist/coordination/store-task-context.js.map +1 -0
- package/dist/hooks/backup-manager.js +273 -0
- package/dist/hooks/backup-manager.js.map +1 -0
- package/dist/hooks/post-edit-validator.js +388 -0
- package/dist/hooks/post-edit-validator.js.map +1 -0
- package/dist/integration/index.js +19 -0
- package/dist/integration/index.js.map +1 -0
- package/dist/integration/task-mode-adapter.js +297 -0
- package/dist/integration/task-mode-adapter.js.map +1 -0
- package/dist/integration/trigger-dev-client.js +253 -0
- package/dist/integration/trigger-dev-client.js.map +1 -0
- package/dist/integration/trigger-dev-webhooks.js +362 -0
- package/dist/integration/trigger-dev-webhooks.js.map +1 -0
- package/dist/lib/artifact-registry.js +4 -0
- package/dist/lib/artifact-registry.js.map +1 -1
- package/dist/lib/connection-pool.js +390 -0
- package/dist/lib/connection-pool.js.map +1 -0
- package/dist/lib/environment-contract.js +258 -0
- package/dist/lib/environment-contract.js.map +1 -0
- package/dist/lib/path-validator.js +14 -5
- package/dist/lib/path-validator.js.map +1 -1
- package/dist/lib/query-optimizer.js +388 -0
- package/dist/lib/query-optimizer.js.map +1 -0
- package/dist/lib/redis-queue-manager.js +5 -1
- package/dist/lib/redis-queue-manager.js.map +1 -1
- package/dist/lib/result-cache.js +285 -0
- package/dist/lib/result-cache.js.map +1 -0
- package/dist/mcp/auth-middleware.js +2 -1
- package/dist/mcp/auth-middleware.js.map +1 -1
- package/dist/mcp/playwright-mcp-server-auth.js +2 -1
- package/dist/mcp/playwright-mcp-server-auth.js.map +1 -1
- package/dist/middleware/authentication.js +317 -0
- package/dist/middleware/authentication.js.map +1 -0
- package/dist/services/authentication.js +669 -0
- package/dist/services/authentication.js.map +1 -0
- package/dist/services/session-management.js +436 -0
- package/dist/services/session-management.js.map +1 -0
- package/dist/services/skill-deployment.js +8 -6
- package/dist/services/skill-deployment.js.map +1 -1
- package/dist/services/user-service.js +710 -0
- package/dist/services/user-service.js.map +1 -0
- package/dist/types/trigger-dev-events.d.js +10 -0
- package/dist/types/trigger-dev-events.d.js.map +1 -0
- package/docs/README.md +240 -0
- package/package.json +15 -4
- package/scripts/build-agent-image.sh +1 -1
- package/scripts/compare-workflow-performance.sh +556 -0
- package/scripts/cost-allocation-tracker.sh +632 -0
- package/scripts/docker-rebuild-all-agents.sh +2 -2
- package/scripts/migrate-to-optimized-workflows.sh +438 -0
- package/scripts/organize-docs.sh +338 -0
- package/scripts/reorganize-tests.sh +280 -0
- package/scripts/trigger-dev-setup.sh +279 -0
- package/tests/README.md +45 -0
- package/.claude/commands/cost-savings-status.md +0 -34
- package/.claude/commands/metrics-summary.md +0 -58
- package/.claude/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +0 -348
- package/.claude/skills/cfn-docker-redis-coordination/README.md +0 -294
- package/.claude/skills/cfn-docker-redis-coordination/SKILL.md +0 -435
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh +0 -650
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh.backup-1763145142 +0 -641
- package/.claude/skills/cfn-docker-redis-coordination/package-lock.json +0 -5259
- package/.claude/skills/cfn-docker-redis-coordination/package.json +0 -40
- package/.claude/skills/cfn-docker-redis-coordination/src/coordinator.ts +0 -801
- package/.claude/skills/cfn-docker-redis-coordination/src/index.ts +0 -42
- package/.claude/skills/cfn-docker-redis-coordination/src/types.ts +0 -351
- package/.claude/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +0 -1464
- package/.claude/skills/cfn-docker-redis-coordination/tsconfig.json +0 -30
- package/.claude/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +0 -228
- package/.claude/skills/cfn-loop-orchestration/helpers/consensus-ts.sh +0 -104
- package/.claude/skills/cfn-loop-orchestration/helpers/consensus.sh +0 -94
- package/.claude/skills/cfn-loop-orchestration/helpers/context-injection.sh +0 -142
- package/.claude/skills/cfn-loop-orchestration/helpers/context-lookup.sh +0 -359
- package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier-ts.sh +0 -123
- package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +0 -71
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +0 -56
- package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager-ts.sh +0 -89
- package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +0 -87
- package/.claude/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +0 -104
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +0 -56
- package/.claude/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +0 -290
- package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator-ts.sh +0 -47
- package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +0 -51
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +0 -1345
- package/.claude/skills/cfn-redis-coordination/AGENT_LOGGING.md +0 -280
- package/.claude/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +0 -209
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +0 -319
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +0 -124
- package/.claude/skills/cfn-redis-coordination/config.json +0 -61
- package/.claude/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +0 -82
- package/.claude/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +0 -274
- package/.claude/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +0 -0
- package/.claude/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +0 -553
- package/.claude/skills/cfn-redis-coordination/jest.config.js +0 -23
- package/.claude/skills/cfn-redis-coordination/package-lock.json +0 -5272
- package/.claude/skills/cfn-redis-coordination/package.json +0 -45
- package/.claude/skills/cfn-redis-coordination/src/agent-logger.ts +0 -446
- package/.claude/skills/cfn-redis-coordination/src/agent-recovery.ts +0 -454
- package/.claude/skills/cfn-redis-coordination/src/completion-reporter.ts +0 -396
- package/.claude/skills/cfn-redis-coordination/src/context-manager.ts +0 -327
- package/.claude/skills/cfn-redis-coordination/src/index.ts +0 -82
- package/.claude/skills/cfn-redis-coordination/src/mode-detector.ts +0 -155
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-client.ts +0 -305
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-functions.ts +0 -283
- package/.claude/skills/cfn-redis-coordination/src/redis-client.ts +0 -654
- package/.claude/skills/cfn-redis-coordination/src/result-collector.ts +0 -437
- package/.claude/skills/cfn-redis-coordination/src/swarm-manager.ts +0 -494
- package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +0 -404
- package/.claude/skills/cfn-redis-coordination/src/task-executor.ts +0 -423
- package/.claude/skills/cfn-redis-coordination/src/types.ts +0 -235
- package/.claude/skills/cfn-redis-coordination/src/waiting-coordinator.ts +0 -587
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +0 -85
- package/.claude/skills/cfn-redis-coordination/test-connection-attempts.js +0 -70
- package/.claude/skills/cfn-redis-coordination/test-mode-simple.js +0 -121
- package/.claude/skills/cfn-redis-coordination/test-redis-check.js +0 -84
- package/.claude/skills/cfn-redis-coordination/test-task-mode-redis.cjs +0 -391
- package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +0 -788
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +0 -67
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +0 -980
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +0 -759
- package/claude-assets/agents/custom/test-mcp-access.md +0 -24
- package/claude-assets/agents/typescript-specialist.md +0 -280
- package/claude-assets/commands/cost-savings-status.md +0 -34
- package/claude-assets/commands/metrics-summary.md +0 -58
- package/claude-assets/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +0 -348
- package/claude-assets/skills/cfn-docker-redis-coordination/README.md +0 -294
- package/claude-assets/skills/cfn-docker-redis-coordination/SKILL.md +0 -435
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh +0 -650
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh.backup-1763145142 +0 -641
- package/claude-assets/skills/cfn-docker-redis-coordination/jest.config.js +0 -37
- package/claude-assets/skills/cfn-docker-redis-coordination/package-lock.json +0 -5259
- package/claude-assets/skills/cfn-docker-redis-coordination/package.json +0 -40
- package/claude-assets/skills/cfn-docker-redis-coordination/src/coordinator.ts +0 -801
- package/claude-assets/skills/cfn-docker-redis-coordination/src/index.ts +0 -42
- package/claude-assets/skills/cfn-docker-redis-coordination/src/types.ts +0 -351
- package/claude-assets/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +0 -1464
- package/claude-assets/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +0 -228
- package/claude-assets/skills/cfn-loop-orchestration/helpers/consensus-ts.sh +0 -104
- package/claude-assets/skills/cfn-loop-orchestration/helpers/consensus.sh +0 -94
- package/claude-assets/skills/cfn-loop-orchestration/helpers/context-injection.sh +0 -142
- package/claude-assets/skills/cfn-loop-orchestration/helpers/context-lookup.sh +0 -359
- package/claude-assets/skills/cfn-loop-orchestration/helpers/deliverable-verifier-ts.sh +0 -123
- package/claude-assets/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +0 -71
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +0 -56
- package/claude-assets/skills/cfn-loop-orchestration/helpers/iteration-manager-ts.sh +0 -89
- package/claude-assets/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +0 -87
- package/claude-assets/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +0 -104
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +0 -56
- package/claude-assets/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +0 -290
- package/claude-assets/skills/cfn-loop-orchestration/helpers/timeout-calculator-ts.sh +0 -47
- package/claude-assets/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +0 -51
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +0 -1345
- package/claude-assets/skills/cfn-redis-cleanup/cleanup-redis.sh +0 -130
- package/claude-assets/skills/cfn-redis-coordination/AGENT_LOGGING.md +0 -280
- package/claude-assets/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +0 -209
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +0 -319
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +0 -124
- package/claude-assets/skills/cfn-redis-coordination/config.json +0 -61
- package/claude-assets/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +0 -82
- package/claude-assets/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +0 -274
- package/claude-assets/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +0 -0
- package/claude-assets/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +0 -553
- package/claude-assets/skills/cfn-redis-coordination/jest.config.js +0 -23
- package/claude-assets/skills/cfn-redis-coordination/package-lock.json +0 -5272
- package/claude-assets/skills/cfn-redis-coordination/package.json +0 -45
- package/claude-assets/skills/cfn-redis-coordination/src/agent-logger.ts +0 -446
- package/claude-assets/skills/cfn-redis-coordination/src/agent-recovery.ts +0 -454
- package/claude-assets/skills/cfn-redis-coordination/src/completion-reporter.ts +0 -396
- package/claude-assets/skills/cfn-redis-coordination/src/context-manager.ts +0 -327
- package/claude-assets/skills/cfn-redis-coordination/src/index.ts +0 -82
- package/claude-assets/skills/cfn-redis-coordination/src/mode-detector.ts +0 -155
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-client.ts +0 -305
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-functions.ts +0 -283
- package/claude-assets/skills/cfn-redis-coordination/src/redis-client.ts +0 -654
- package/claude-assets/skills/cfn-redis-coordination/src/result-collector.ts +0 -437
- package/claude-assets/skills/cfn-redis-coordination/src/swarm-manager.ts +0 -494
- package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +0 -404
- package/claude-assets/skills/cfn-redis-coordination/src/task-executor.ts +0 -423
- package/claude-assets/skills/cfn-redis-coordination/src/types.ts +0 -235
- package/claude-assets/skills/cfn-redis-coordination/src/waiting-coordinator.ts +0 -587
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +0 -85
- package/claude-assets/skills/cfn-redis-coordination/test-connection-attempts.js +0 -70
- package/claude-assets/skills/cfn-redis-coordination/test-mode-simple.js +0 -121
- package/claude-assets/skills/cfn-redis-coordination/test-redis-check.js +0 -84
- package/claude-assets/skills/cfn-redis-coordination/test-task-mode-redis.cjs +0 -391
- package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +0 -788
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +0 -67
- package/claude-assets/skills/cfn-redis-data-extraction/SKILL.md +0 -442
- package/claude-assets/skills/cfn-redis-data-extraction/extract.sh +0 -306
- package/dist/coordination/index.js +0 -25
- package/dist/coordination/index.js.map +0 -1
- package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +0 -405
- package/docs/MEMORY_CLEANUP_GUIDE.md +0 -358
- package/docs/MEMORY_LEAK_FIX_SUMMARY.md +0 -322
- package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +0 -319
- package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +0 -574
- package/tests/test-memory-leak-task-mode.sh +0 -435
- /package/.claude/skills/cfn-loop-orchestration/{inject-loop-context.sh → archive/legacy-bash/inject-loop-context.sh} +0 -0
- /package/.claude/skills/cfn-loop-orchestration/{monitor-execution.sh → archive/legacy-bash/monitor-execution.sh} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{agent-log.sh → agent-log.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{agent-recovery.sh → agent-recovery.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{analyze-task-complexity.sh → analyze-task-complexity.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/bash-wrappers/{store-context.sh → store-context.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cancel-swarm.sh → cancel-swarm.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cfn-loop-exec.sh → cfn-loop-exec.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cfn-loop-relaunch.sh → cfn-loop-relaunch.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{collect-confidence-scores.sh → collect-confidence-scores.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{collect-results.sh → collect-results.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{complete-swarm.sh → complete-swarm.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{get-context.sh → get-context.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{get-success-criteria.sh → get-success-criteria.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{invoke-waiting-mode.sh → invoke-waiting-mode.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{redis-cli-wrapper.sh → redis-cli-wrapper.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{redis-functions.sh → redis-functions.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{report-completion.sh → report-completion.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{store-context.sh → store-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-loop-orchestration/{inject-loop-context.sh → archive/legacy-bash/inject-loop-context.sh} +0 -0
- /package/claude-assets/skills/cfn-loop-orchestration/{monitor-execution.sh → archive/legacy-bash/monitor-execution.sh} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{agent-log.sh → agent-log.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{agent-recovery.sh → agent-recovery.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{analyze-task-complexity.sh → analyze-task-complexity.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/bash-wrappers/{store-context.sh → store-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cancel-swarm.sh → cancel-swarm.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cfn-loop-exec.sh → cfn-loop-exec.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cfn-loop-relaunch.sh → cfn-loop-relaunch.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{collect-confidence-scores.sh → collect-confidence-scores.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{collect-results.sh → collect-results.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{complete-swarm.sh → complete-swarm.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{get-context.sh → get-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{get-success-criteria.sh → get-success-criteria.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{invoke-waiting-mode.sh → invoke-waiting-mode.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{redis-cli-wrapper.sh → redis-cli-wrapper.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{redis-functions.sh → redis-functions.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{report-completion.sh → report-completion.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{store-context.sh → store-context.sh.backup} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/agent-spawn.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Agent Spawning CLI - Direct agent process spawning\r\n *\r\n * Usage:\r\n * npx cfn-spawn agent <type> [options]\r\n * npx cfn-spawn <type> [options] (agent is implied)\r\n *\r\n * Examples:\r\n * npx cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n * npx cfn-spawn researcher --task-id task-123 --iteration 1\r\n */\r\n\r\nimport { spawn, execFileSync } from 'child_process';\r\nimport { resolve } from 'path';\r\n\r\ninterface AgentSpawnOptions {\r\n agentType: string;\r\n agentId?: string;\r\n taskId?: string;\r\n iteration?: number;\r\n context?: string;\r\n mode?: string;\r\n priority?: number;\r\n parentTaskId?: string;\r\n}\r\n\r\n/**\r\n * SECURITY: Parameter validation to prevent command injection (CVSS 8.9)\r\n * Validates all parameters that will be passed to execFileSync()\r\n */\r\n\r\n/**\r\n * Validates taskId format to prevent command injection attacks\r\n * Pattern: alphanumeric, underscore, hyphen only, 1-64 chars\r\n */\r\nfunction validateTaskId(taskId: string): { valid: boolean; error?: string } {\r\n if (typeof taskId !== 'string' || taskId.length === 0) {\r\n return { valid: false, error: 'Task ID must be a non-empty string' };\r\n }\r\n\r\n const taskIdPattern = /^[a-zA-Z0-9_-]{1,64}$/;\r\n if (!taskIdPattern.test(taskId)) {\r\n return {\r\n valid: false,\r\n error: 'Invalid task ID format - must contain only alphanumeric characters, underscores, and hyphens (max 64 chars)'\r\n };\r\n }\r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Validates Redis host to prevent command injection\r\n * Allows: hostnames, domain names, localhost, IPv4, IPv6 (::1)\r\n */\r\nfunction validateRedisHost(host: string): { valid: boolean; error?: string } {\r\n if (typeof host !== 'string' || host.length === 0) {\r\n return { valid: false, error: 'Redis host must be a non-empty string' };\r\n }\r\n\r\n // Pattern: alphanumeric, hyphens, dots (for domains), plus special IPv6 loopback\r\n const hostPattern = /^[a-zA-Z0-9.-]+$|^::1$/;\r\n if (!hostPattern.test(host)) {\r\n return { valid: false, error: 'Invalid Redis host format' };\r\n }\r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Validates Redis port to prevent command injection\r\n * Range: 1-65535\r\n */\r\nfunction validateRedisPort(port: string): { valid: boolean; error?: string } {\r\n if (typeof port !== 'string' || port.length === 0) {\r\n return { valid: false, error: 'Redis port must be a non-empty string' };\r\n }\r\n\r\n const portNum = parseInt(port, 10);\r\n if (isNaN(portNum) || portNum < 1 || portNum > 65535) {\r\n return { valid: false, error: 'Invalid Redis port - must be between 1 and 65535' };\r\n }\r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Safely retrieves context from Redis using execFileSync()\r\n * Prevents command injection by using array-based arguments instead of template literals\r\n */\r\nfunction getRedisContextSafely(\r\n taskId: string,\r\n redisHost: string,\r\n redisPort: string,\r\n contextKey: string\r\n): string {\r\n try {\r\n // Validate all parameters BEFORE executing\r\n const taskIdValidation = validateTaskId(taskId);\r\n if (!taskIdValidation.valid) {\r\n console.warn(`[cfn-spawn] Invalid task ID: ${taskIdValidation.error}`);\r\n return '';\r\n }\r\n\r\n const hostValidation = validateRedisHost(redisHost);\r\n if (!hostValidation.valid) {\r\n console.warn(`[cfn-spawn] Invalid Redis host: ${hostValidation.error}`);\r\n return '';\r\n }\r\n\r\n const portValidation = validateRedisPort(redisPort);\r\n if (!portValidation.valid) {\r\n console.warn(`[cfn-spawn] Invalid Redis port: ${portValidation.error}`);\r\n return '';\r\n }\r\n\r\n // All parameters validated - now execute safely with execFileSync()\r\n // Using array arguments prevents shell interpolation of metacharacters\r\n const redisKey = `swarm:${taskId}:${contextKey}`;\r\n const result = execFileSync('redis-cli', [\r\n '-h', redisHost,\r\n '-p', redisPort,\r\n 'get',\r\n redisKey\r\n ], { encoding: 'utf8' });\r\n\r\n const trimmed = result.trim();\r\n return trimmed === '(nil)' ? '' : trimmed;\r\n } catch (e) {\r\n // Redis not available or key doesn't exist - fail silently\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Parse command line arguments for agent spawning\r\n */\r\nexport function parseAgentArgs(args: string[]): AgentSpawnOptions | null {\r\n // Handle both \"agent <type>\" and \"<type>\" patterns\r\n let agentType: string;\r\n let optionArgs: string[];\r\n\r\n if (args[0] === 'agent') {\r\n agentType = args[1];\r\n optionArgs = args.slice(2);\r\n } else {\r\n agentType = args[0];\r\n optionArgs = args.slice(1);\r\n }\r\n\r\n // Validate agent type exists and is not a flag\r\n if (!agentType || agentType.startsWith('--')) {\r\n console.error('Error: Agent type is required');\r\n console.error('Usage: cfn-spawn agent <type> [options]');\r\n return null;\r\n }\r\n\r\n const options: AgentSpawnOptions = { agentType };\r\n\r\n // Parse optional parameters\r\n for (let i = 0; i < optionArgs.length; i += 2) {\r\n const key = optionArgs[i];\r\n const value = optionArgs[i + 1];\r\n\r\n switch (key) {\r\n case '--agent-id':\r\n options.agentId = value;\r\n break;\r\n case '--task-id':\r\n options.taskId = value;\r\n break;\r\n case '--iteration':\r\n options.iteration = parseInt(value, 10);\r\n break;\r\n case '--context':\r\n options.context = value;\r\n break;\r\n case '--mode':\r\n options.mode = value;\r\n break;\r\n case '--priority':\r\n options.priority = parseInt(value, 10);\r\n break;\r\n case '--parent-task':\r\n case '--parent-task-id':\r\n options.parentTaskId = value;\r\n break;\r\n default:\r\n console.warn(`Unknown option: ${key}`);\r\n }\r\n }\r\n\r\n return options;\r\n}\r\n\r\n/**\r\n * Spawn an agent process using npx claude-flow-novice agent\r\n *\r\n * This is a wrapper/alias for the existing claude-flow-novice agent spawning mechanism\r\n * Provides the cfn-spawn naming pattern while delegating to the working implementation\r\n */\r\nexport async function spawnAgent(options: AgentSpawnOptions): Promise<void> {\r\n const { agentType, agentId, taskId, iteration, context, mode, priority, parentTaskId } = options;\r\n\r\n console.log(`[cfn-spawn] Spawning agent: ${agentType}`);\r\n if (agentId) console.log(`[cfn-spawn] Agent ID: ${agentId}`);\r\n if (taskId) console.log(`[cfn-spawn] Task ID: ${taskId}`);\r\n if (iteration) console.log(`[cfn-spawn] Iteration: ${iteration}`);\r\n if (context) console.log(`[cfn-spawn] Context: ${context}`);\r\n if (mode) console.log(`[cfn-spawn] Mode: ${mode}`);\r\n\r\n // Build command arguments for npx claude-flow-novice agent\r\n const claudeArgs = ['claude-flow-novice', 'agent', agentType];\r\n\r\n // Add optional parameters\r\n if (agentId) {\r\n claudeArgs.push('--agent-id', agentId);\r\n }\r\n if (taskId) {\r\n claudeArgs.push('--task-id', taskId);\r\n }\r\n if (iteration) {\r\n claudeArgs.push('--iteration', iteration.toString());\r\n }\r\n if (context) {\r\n claudeArgs.push('--context', context);\r\n }\r\n if (mode) {\r\n claudeArgs.push('--mode', mode);\r\n }\r\n if (priority) {\r\n claudeArgs.push('--priority', priority.toString());\r\n }\r\n if (parentTaskId) {\r\n claudeArgs.push('--parent-task-id', parentTaskId);\r\n }\r\n\r\n // Fetch epic context from Redis if available\r\n let epicContext = '';\r\n let phaseContext = '';\r\n let successCriteria = '';\r\n\r\n if (taskId) {\r\n // SECURITY FIX (CVSS 8.9): Use safe parameter validation and execFileSync()\r\n // Prevent command injection by validating all parameters BEFORE execution\r\n const redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\n const redisPort = process.env.CFN_REDIS_PORT || '6379';\r\n\r\n // Validate Redis connection parameters\r\n const hostValidation = validateRedisHost(redisHost);\r\n const portValidation = validateRedisPort(redisPort);\r\n\r\n if (hostValidation.valid && portValidation.valid) {\r\n // Try to read epic-level context from Redis\r\n epicContext = getRedisContextSafely(taskId, redisHost, redisPort, 'epic-context');\r\n\r\n // Try to read phase-specific context\r\n phaseContext = getRedisContextSafely(taskId, redisHost, redisPort, 'phase-context');\r\n\r\n // Try to read success criteria\r\n successCriteria = getRedisContextSafely(taskId, redisHost, redisPort, 'success-criteria');\r\n\r\n if (epicContext) {\r\n console.log(`[cfn-spawn] Epic context loaded from Redis`);\r\n }\r\n } else {\r\n console.warn(`[cfn-spawn] Invalid Redis configuration - skipping context load`);\r\n if (!hostValidation.valid) console.warn(`[cfn-spawn] ${hostValidation.error}`);\r\n if (!portValidation.valid) console.warn(`[cfn-spawn] ${portValidation.error}`);\r\n }\r\n }\r\n\r\n // Add environment variables for agent context - WHITELIST ONLY APPROACH\r\n // SECURITY FIX: Do not use ...process.env spread which exposes ALL variables including secrets\r\n // Instead, explicitly whitelist safe variables to pass to spawned process\r\n const safeEnvVars = [\r\n 'CFN_REDIS_HOST',\r\n 'CFN_REDIS_PORT',\r\n 'CFN_REDIS_PASSWORD', // CRITICAL: Required for Redis authentication\r\n 'CFN_REDIS_URL',\r\n 'REDIS_PASSWORD', // Fallback for Redis password\r\n 'CFN_MEMORY_BUDGET',\r\n 'CFN_API_HOST',\r\n 'CFN_API_PORT',\r\n 'CFN_LOG_LEVEL',\r\n 'CFN_LOG_FORMAT',\r\n 'CFN_CONTAINER_MODE',\r\n 'CFN_DOCKER_SOCKET',\r\n 'CFN_NETWORK_NAME',\r\n 'CFN_CUSTOM_ROUTING',\r\n 'CFN_DEFAULT_PROVIDER',\r\n 'NODE_ENV',\r\n 'PATH',\r\n 'HOME',\r\n 'PWD' // Required for working directory context\r\n ];\r\n\r\n // Build whitelist-only env object\r\n const env: Record<string, string> = {};\r\n\r\n // Add whitelisted CFN variables\r\n for (const key of safeEnvVars) {\r\n const value = process.env[key];\r\n if (value !== undefined) {\r\n env[key] = value;\r\n }\r\n }\r\n\r\n // Add API key only when explicitly needed (with strict validation)\r\n if (process.env.ANTHROPIC_API_KEY) {\r\n // Validate format: should start with \"sk-\" or \"sk-ant-\"\r\n if (process.env.ANTHROPIC_API_KEY.match(/^sk-[a-zA-Z0-9-]+$/)) {\r\n env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;\r\n } else {\r\n console.warn('[cfn-spawn] Warning: ANTHROPIC_API_KEY format invalid, not passing to agent');\r\n }\r\n }\r\n\r\n // Add task and execution context variables\r\n env.AGENT_TYPE = agentType;\r\n env.TASK_ID = taskId || '';\r\n env.ITERATION = iteration?.toString() || '1';\r\n env.CONTEXT = context || '';\r\n env.MODE = mode || 'cli';\r\n env.PRIORITY = priority?.toString() || '5';\r\n env.PARENT_TASK_ID = parentTaskId || '';\r\n\r\n // Epic-level context from Redis (sanitized)\r\n env.EPIC_CONTEXT = epicContext;\r\n env.PHASE_CONTEXT = phaseContext;\r\n env.SUCCESS_CRITERIA = successCriteria;\r\n\r\n console.log(`[cfn-spawn] Executing: npx ${claudeArgs.join(' ')}`);\r\n\r\n // Spawn the claude-flow-novice agent process\r\n const agentProcess = spawn('npx', claudeArgs, {\r\n stdio: 'inherit',\r\n env,\r\n cwd: process.cwd()\r\n });\r\n\r\n // Handle process exit\r\n agentProcess.on('exit', (code, signal) => {\r\n if (code === 0) {\r\n console.log(`[cfn-spawn] Agent ${agentType} completed successfully`);\r\n } else {\r\n console.error(`[cfn-spawn] Agent ${agentType} exited with code ${code}, signal ${signal}`);\r\n }\r\n process.exit(code || 0);\r\n });\r\n\r\n // Handle process errors\r\n agentProcess.on('error', (err) => {\r\n console.error(`[cfn-spawn] Failed to spawn agent ${agentType}:`, err.message);\r\n process.exit(1);\r\n });\r\n\r\n // Cleanup on parent exit\r\n process.on('SIGINT', () => {\r\n console.log('\\n[cfn-spawn] Received SIGINT, terminating agent...');\r\n agentProcess.kill('SIGINT');\r\n });\r\n\r\n process.on('SIGTERM', () => {\r\n console.log('\\n[cfn-spawn] Received SIGTERM, terminating agent...');\r\n agentProcess.kill('SIGTERM');\r\n });\r\n}\r\n\r\n/**\r\n * Build task description for the agent\r\n */\r\nexport function buildTaskDescription(\r\n agentType: string,\r\n taskId?: string,\r\n iteration?: number,\r\n context?: string\r\n): string {\r\n let desc = `Execute task as ${agentType} agent`;\r\n\r\n if (taskId) desc += ` for task ${taskId}`;\r\n if (iteration !== undefined) desc += ` (iteration ${iteration})`;\r\n if (context) desc += `: ${context}`;\r\n\r\n return desc;\r\n}\r\n\r\n/**\r\n * Main CLI entry point\r\n */\r\nexport async function main(args: string[] = process.argv.slice(2)): Promise<void> {\r\n // Show help if requested\r\n if (args.includes('--help') || args.includes('-h')) {\r\n console.log(`\r\ncfn-spawn - Claude Flow Novice Agent Spawner\r\n\r\nUsage:\r\n cfn-spawn agent <type> [options]\r\n cfn-spawn <type> [options] (agent is implied)\r\n\r\nOptions:\r\n --agent-id <id> Explicit agent identifier (overrides auto-generation)\r\n --task-id <id> Task identifier\r\n --iteration <n> Iteration number\r\n --context <text> Context description\r\n --mode <mode> Execution mode (cli, api, hybrid)\r\n --priority <1-10> Task priority\r\n --parent-task-id <id> Parent task identifier\r\n\r\nExamples:\r\n cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n cfn-spawn coder --task-id auth-impl --context \"Implement JWT auth\"\r\n cfn-spawn reviewer --task-id auth-impl --iteration 2 --mode cli\r\n cfn-spawn tester --agent-id tester-1-1 --task-id test-phase --iteration 1\r\n `);\r\n return;\r\n }\r\n\r\n // Parse arguments\r\n const options = parseAgentArgs(args);\r\n if (!options) {\r\n process.exit(1);\r\n }\r\n\r\n // Spawn the agent\r\n await spawnAgent(options);\r\n}\r\n\r\n// Run if called directly\r\n// ES module check - compare import.meta.url with the executed file\r\nconst isMainModule = import.meta.url.endsWith(process.argv[1]?.replace(/\\\\/g, '/') || '');\r\nif (isMainModule) {\r\n main().catch((err) => {\r\n console.error('[cfn-spawn] Fatal error:', err);\r\n process.exit(1);\r\n });\r\n}\r\n"],"names":["spawn","execFileSync","validateTaskId","taskId","length","valid","error","taskIdPattern","test","validateRedisHost","host","hostPattern","validateRedisPort","port","portNum","parseInt","isNaN","getRedisContextSafely","redisHost","redisPort","contextKey","taskIdValidation","console","warn","hostValidation","portValidation","redisKey","result","encoding","trimmed","trim","e","parseAgentArgs","args","agentType","optionArgs","slice","startsWith","options","i","key","value","agentId","iteration","context","mode","priority","parentTaskId","spawnAgent","log","claudeArgs","push","toString","epicContext","phaseContext","successCriteria","process","env","CFN_REDIS_HOST","CFN_REDIS_PORT","safeEnvVars","undefined","ANTHROPIC_API_KEY","match","AGENT_TYPE","TASK_ID","ITERATION","CONTEXT","MODE","PRIORITY","PARENT_TASK_ID","EPIC_CONTEXT","PHASE_CONTEXT","SUCCESS_CRITERIA","join","agentProcess","stdio","cwd","on","code","signal","exit","err","message","kill","buildTaskDescription","desc","main","argv","includes","isMainModule","url","endsWith","replace","catch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/agent-spawn.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Agent Spawning CLI - Direct agent process spawning\r\n *\r\n * Usage:\r\n * npx cfn-spawn agent <type> [options]\r\n * npx cfn-spawn <type> [options] (agent is implied)\r\n *\r\n * Examples:\r\n * npx cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n * npx cfn-spawn researcher --task-id task-123 --iteration 1\r\n */\r\n\r\nimport { spawn, execFileSync } from 'child_process';\r\nimport { resolve } from 'path';\r\n\r\ninterface AgentSpawnOptions {\r\n agentType: string;\r\n agentId?: string;\r\n taskId?: string;\r\n iteration?: number;\r\n context?: string;\r\n mode?: string;\r\n priority?: number;\r\n parentTaskId?: string;\r\n}\r\n\r\n/**\r\n * SECURITY: Parameter validation to prevent command injection (CVSS 8.9)\r\n * Validates all parameters that will be passed to execFileSync()\r\n */\r\n\r\n/**\r\n * Validates taskId format to prevent command injection attacks\r\n * Pattern: optional namespace prefix (e.g., \"cli:\", \"task:\"), alphanumeric, underscore, hyphen, dot (max 64 chars)\r\n * Examples: \"task-123\", \"cli:task-456\", \"orchestrator:batch-789\"\r\n */\r\nfunction validateTaskId(taskId: string): { valid: boolean; error?: string } {\r\n if (typeof taskId !== 'string' || taskId.length === 0) {\r\n return { valid: false, error: 'Task ID must be a non-empty string' };\r\n }\r\n\r\n // Allow optional namespace prefix (lowercase letters + colon), followed by alphanumeric/underscore/hyphen/dot\r\n const taskIdPattern = /^([a-z]+:)?[a-zA-Z0-9_.-]{1,64}$/;\r\n if (!taskIdPattern.test(taskId)) {\r\n return {\r\n valid: false,\r\n error: 'Invalid task ID format - must contain optional namespace prefix (e.g., \"cli:\") and alphanumeric characters, underscores, hyphens, or dots (max 64 chars)'\r\n };\r\n }\r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Validates Redis host to prevent command injection\r\n * Allows: hostnames, domain names, localhost, IPv4, IPv6 (::1)\r\n */\r\nfunction validateRedisHost(host: string): { valid: boolean; error?: string } {\r\n if (typeof host !== 'string' || host.length === 0) {\r\n return { valid: false, error: 'Redis host must be a non-empty string' };\r\n }\r\n\r\n // Pattern: alphanumeric, hyphens, dots (for domains), plus special IPv6 loopback\r\n const hostPattern = /^[a-zA-Z0-9.-]+$|^::1$/;\r\n if (!hostPattern.test(host)) {\r\n return { valid: false, error: 'Invalid Redis host format' };\r\n }\r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Validates Redis port to prevent command injection\r\n * Range: 1-65535\r\n */\r\nfunction validateRedisPort(port: string): { valid: boolean; error?: string } {\r\n if (typeof port !== 'string' || port.length === 0) {\r\n return { valid: false, error: 'Redis port must be a non-empty string' };\r\n }\r\n\r\n const portNum = parseInt(port, 10);\r\n if (isNaN(portNum) || portNum < 1 || portNum > 65535) {\r\n return { valid: false, error: 'Invalid Redis port - must be between 1 and 65535' };\r\n }\r\n return { valid: true };\r\n}\r\n\r\n/**\r\n * Safely retrieves context from Redis using execFileSync()\r\n * Prevents command injection by using array-based arguments instead of template literals\r\n */\r\nfunction getRedisContextSafely(\r\n taskId: string,\r\n redisHost: string,\r\n redisPort: string,\r\n contextKey: string\r\n): string {\r\n try {\r\n // Validate all parameters BEFORE executing\r\n const taskIdValidation = validateTaskId(taskId);\r\n if (!taskIdValidation.valid) {\r\n console.warn(`[cfn-spawn] Invalid task ID: ${taskIdValidation.error}`);\r\n return '';\r\n }\r\n\r\n const hostValidation = validateRedisHost(redisHost);\r\n if (!hostValidation.valid) {\r\n console.warn(`[cfn-spawn] Invalid Redis host: ${hostValidation.error}`);\r\n return '';\r\n }\r\n\r\n const portValidation = validateRedisPort(redisPort);\r\n if (!portValidation.valid) {\r\n console.warn(`[cfn-spawn] Invalid Redis port: ${portValidation.error}`);\r\n return '';\r\n }\r\n\r\n // All parameters validated - now execute safely with execFileSync()\r\n // Using array arguments prevents shell interpolation of metacharacters\r\n const redisKey = `swarm:${taskId}:${contextKey}`;\r\n const result = execFileSync('redis-cli', [\r\n '-h', redisHost,\r\n '-p', redisPort,\r\n 'get',\r\n redisKey\r\n ], { encoding: 'utf8' });\r\n\r\n const trimmed = result.trim();\r\n return trimmed === '(nil)' ? '' : trimmed;\r\n } catch (e) {\r\n // Redis not available or key doesn't exist - fail silently\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Parse command line arguments for agent spawning\r\n */\r\nexport function parseAgentArgs(args: string[]): AgentSpawnOptions | null {\r\n // Handle both \"agent <type>\" and \"<type>\" patterns\r\n let agentType: string;\r\n let optionArgs: string[];\r\n\r\n if (args[0] === 'agent') {\r\n agentType = args[1];\r\n optionArgs = args.slice(2);\r\n } else {\r\n agentType = args[0];\r\n optionArgs = args.slice(1);\r\n }\r\n\r\n // Validate agent type exists and is not a flag\r\n if (!agentType || agentType.startsWith('--')) {\r\n console.error('Error: Agent type is required');\r\n console.error('Usage: cfn-spawn agent <type> [options]');\r\n return null;\r\n }\r\n\r\n const options: AgentSpawnOptions = { agentType };\r\n\r\n // Parse optional parameters\r\n for (let i = 0; i < optionArgs.length; i += 2) {\r\n const key = optionArgs[i];\r\n const value = optionArgs[i + 1];\r\n\r\n switch (key) {\r\n case '--agent-id':\r\n options.agentId = value;\r\n break;\r\n case '--task-id':\r\n options.taskId = value;\r\n break;\r\n case '--iteration':\r\n options.iteration = parseInt(value, 10);\r\n break;\r\n case '--context':\r\n options.context = value;\r\n break;\r\n case '--mode':\r\n options.mode = value;\r\n break;\r\n case '--priority':\r\n options.priority = parseInt(value, 10);\r\n break;\r\n case '--parent-task':\r\n case '--parent-task-id':\r\n options.parentTaskId = value;\r\n break;\r\n default:\r\n console.warn(`Unknown option: ${key}`);\r\n }\r\n }\r\n\r\n return options;\r\n}\r\n\r\n/**\r\n * Spawn an agent process using npx claude-flow-novice agent\r\n *\r\n * This is a wrapper/alias for the existing claude-flow-novice agent spawning mechanism\r\n * Provides the cfn-spawn naming pattern while delegating to the working implementation\r\n */\r\nexport async function spawnAgent(options: AgentSpawnOptions): Promise<void> {\r\n const { agentType, agentId, taskId, iteration, context, mode, priority, parentTaskId } = options;\r\n\r\n console.log(`[cfn-spawn] Spawning agent: ${agentType}`);\r\n if (agentId) console.log(`[cfn-spawn] Agent ID: ${agentId}`);\r\n if (taskId) console.log(`[cfn-spawn] Task ID: ${taskId}`);\r\n if (iteration) console.log(`[cfn-spawn] Iteration: ${iteration}`);\r\n if (context) console.log(`[cfn-spawn] Context: ${context}`);\r\n if (mode) console.log(`[cfn-spawn] Mode: ${mode}`);\r\n\r\n // Build command arguments for npx claude-flow-novice agent\r\n const claudeArgs = ['claude-flow-novice', 'agent', agentType];\r\n\r\n // Add optional parameters\r\n if (agentId) {\r\n claudeArgs.push('--agent-id', agentId);\r\n }\r\n if (taskId) {\r\n claudeArgs.push('--task-id', taskId);\r\n }\r\n if (iteration) {\r\n claudeArgs.push('--iteration', iteration.toString());\r\n }\r\n if (context) {\r\n claudeArgs.push('--context', context);\r\n }\r\n if (mode) {\r\n claudeArgs.push('--mode', mode);\r\n }\r\n if (priority) {\r\n claudeArgs.push('--priority', priority.toString());\r\n }\r\n if (parentTaskId) {\r\n claudeArgs.push('--parent-task-id', parentTaskId);\r\n }\r\n\r\n // Fetch epic context from Redis if available\r\n let epicContext = '';\r\n let phaseContext = '';\r\n let successCriteria = '';\r\n\r\n if (taskId) {\r\n // SECURITY FIX (CVSS 8.9): Use safe parameter validation and execFileSync()\r\n // Prevent command injection by validating all parameters BEFORE execution\r\n // FIX: Default to 'localhost' for CLI mode (host execution), not 'cfn-redis' (Docker)\r\n const redisHost = process.env.CFN_REDIS_HOST || 'localhost';\r\n const redisPort = process.env.CFN_REDIS_PORT || '6379';\r\n\r\n // Validate Redis connection parameters\r\n const hostValidation = validateRedisHost(redisHost);\r\n const portValidation = validateRedisPort(redisPort);\r\n\r\n if (hostValidation.valid && portValidation.valid) {\r\n // Try to read epic-level context from Redis\r\n epicContext = getRedisContextSafely(taskId, redisHost, redisPort, 'epic-context');\r\n\r\n // Try to read phase-specific context\r\n phaseContext = getRedisContextSafely(taskId, redisHost, redisPort, 'phase-context');\r\n\r\n // Try to read success criteria\r\n successCriteria = getRedisContextSafely(taskId, redisHost, redisPort, 'success-criteria');\r\n\r\n if (epicContext) {\r\n console.log(`[cfn-spawn] Epic context loaded from Redis`);\r\n }\r\n } else {\r\n console.warn(`[cfn-spawn] Invalid Redis configuration - skipping context load`);\r\n if (!hostValidation.valid) console.warn(`[cfn-spawn] ${hostValidation.error}`);\r\n if (!portValidation.valid) console.warn(`[cfn-spawn] ${portValidation.error}`);\r\n }\r\n }\r\n\r\n // Add environment variables for agent context - WHITELIST ONLY APPROACH\r\n // SECURITY FIX: Do not use ...process.env spread which exposes ALL variables including secrets\r\n // Instead, explicitly whitelist safe variables to pass to spawned process\r\n const safeEnvVars = [\r\n 'CFN_REDIS_HOST',\r\n 'CFN_REDIS_PORT',\r\n 'CFN_REDIS_PASSWORD', // CRITICAL: Required for Redis authentication\r\n 'CFN_REDIS_URL',\r\n 'REDIS_PASSWORD', // Fallback for Redis password\r\n 'CFN_MEMORY_BUDGET',\r\n 'CFN_API_HOST',\r\n 'CFN_API_PORT',\r\n 'CFN_LOG_LEVEL',\r\n 'CFN_LOG_FORMAT',\r\n 'CFN_CONTAINER_MODE',\r\n 'CFN_DOCKER_SOCKET',\r\n 'CFN_NETWORK_NAME',\r\n 'CFN_CUSTOM_ROUTING',\r\n 'CFN_DEFAULT_PROVIDER',\r\n 'NODE_ENV',\r\n 'PATH',\r\n 'HOME',\r\n 'PWD' // Required for working directory context\r\n ];\r\n\r\n // Build whitelist-only env object\r\n const env: Record<string, string> = {};\r\n\r\n // Add whitelisted CFN variables\r\n for (const key of safeEnvVars) {\r\n const value = process.env[key];\r\n if (value !== undefined) {\r\n env[key] = value;\r\n }\r\n }\r\n\r\n // Add API key only when explicitly needed (with strict validation)\r\n if (process.env.ANTHROPIC_API_KEY) {\r\n // Validate format: should start with \"sk-\" or \"sk-ant-\"\r\n if (process.env.ANTHROPIC_API_KEY.match(/^sk-[a-zA-Z0-9-]+$/)) {\r\n env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;\r\n } else {\r\n console.warn('[cfn-spawn] Warning: ANTHROPIC_API_KEY format invalid, not passing to agent');\r\n }\r\n }\r\n\r\n // Add task and execution context variables\r\n env.AGENT_TYPE = agentType;\r\n env.TASK_ID = taskId || '';\r\n env.ITERATION = iteration?.toString() || '1';\r\n env.CONTEXT = context || '';\r\n env.MODE = mode || 'cli';\r\n env.PRIORITY = priority?.toString() || '5';\r\n env.PARENT_TASK_ID = parentTaskId || '';\r\n\r\n // Epic-level context from Redis (sanitized)\r\n env.EPIC_CONTEXT = epicContext;\r\n env.PHASE_CONTEXT = phaseContext;\r\n env.SUCCESS_CRITERIA = successCriteria;\r\n\r\n console.log(`[cfn-spawn] Executing: npx ${claudeArgs.join(' ')}`);\r\n\r\n // Spawn the claude-flow-novice agent process\r\n const agentProcess = spawn('npx', claudeArgs, {\r\n stdio: 'inherit',\r\n env,\r\n cwd: process.cwd()\r\n });\r\n\r\n // Handle process exit\r\n agentProcess.on('exit', (code, signal) => {\r\n if (code === 0) {\r\n console.log(`[cfn-spawn] Agent ${agentType} completed successfully`);\r\n } else {\r\n console.error(`[cfn-spawn] Agent ${agentType} exited with code ${code}, signal ${signal}`);\r\n }\r\n process.exit(code || 0);\r\n });\r\n\r\n // Handle process errors\r\n agentProcess.on('error', (err) => {\r\n console.error(`[cfn-spawn] Failed to spawn agent ${agentType}:`, err.message);\r\n process.exit(1);\r\n });\r\n\r\n // Cleanup on parent exit\r\n process.on('SIGINT', () => {\r\n console.log('\\n[cfn-spawn] Received SIGINT, terminating agent...');\r\n agentProcess.kill('SIGINT');\r\n });\r\n\r\n process.on('SIGTERM', () => {\r\n console.log('\\n[cfn-spawn] Received SIGTERM, terminating agent...');\r\n agentProcess.kill('SIGTERM');\r\n });\r\n}\r\n\r\n/**\r\n * Build task description for the agent\r\n */\r\nexport function buildTaskDescription(\r\n agentType: string,\r\n taskId?: string,\r\n iteration?: number,\r\n context?: string\r\n): string {\r\n let desc = `Execute task as ${agentType} agent`;\r\n\r\n if (taskId) desc += ` for task ${taskId}`;\r\n if (iteration !== undefined) desc += ` (iteration ${iteration})`;\r\n if (context) desc += `: ${context}`;\r\n\r\n return desc;\r\n}\r\n\r\n/**\r\n * Main CLI entry point\r\n */\r\nexport async function main(args: string[] = process.argv.slice(2)): Promise<void> {\r\n // Show help if requested\r\n if (args.includes('--help') || args.includes('-h')) {\r\n console.log(`\r\ncfn-spawn - Claude Flow Novice Agent Spawner\r\n\r\nUsage:\r\n cfn-spawn agent <type> [options]\r\n cfn-spawn <type> [options] (agent is implied)\r\n\r\nOptions:\r\n --agent-id <id> Explicit agent identifier (overrides auto-generation)\r\n --task-id <id> Task identifier\r\n --iteration <n> Iteration number\r\n --context <text> Context description\r\n --mode <mode> Execution mode (cli, api, hybrid)\r\n --priority <1-10> Task priority\r\n --parent-task-id <id> Parent task identifier\r\n\r\nExamples:\r\n cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n cfn-spawn coder --task-id auth-impl --context \"Implement JWT auth\"\r\n cfn-spawn reviewer --task-id auth-impl --iteration 2 --mode cli\r\n cfn-spawn tester --agent-id tester-1-1 --task-id test-phase --iteration 1\r\n `);\r\n return;\r\n }\r\n\r\n // Parse arguments\r\n const options = parseAgentArgs(args);\r\n if (!options) {\r\n process.exit(1);\r\n }\r\n\r\n // Spawn the agent\r\n await spawnAgent(options);\r\n}\r\n\r\n// Run if called directly\r\n// ES module check - compare import.meta.url with the executed file\r\nconst isMainModule = import.meta.url.endsWith(process.argv[1]?.replace(/\\\\/g, '/') || '');\r\nif (isMainModule) {\r\n main().catch((err) => {\r\n console.error('[cfn-spawn] Fatal error:', err);\r\n process.exit(1);\r\n });\r\n}\r\n"],"names":["spawn","execFileSync","validateTaskId","taskId","length","valid","error","taskIdPattern","test","validateRedisHost","host","hostPattern","validateRedisPort","port","portNum","parseInt","isNaN","getRedisContextSafely","redisHost","redisPort","contextKey","taskIdValidation","console","warn","hostValidation","portValidation","redisKey","result","encoding","trimmed","trim","e","parseAgentArgs","args","agentType","optionArgs","slice","startsWith","options","i","key","value","agentId","iteration","context","mode","priority","parentTaskId","spawnAgent","log","claudeArgs","push","toString","epicContext","phaseContext","successCriteria","process","env","CFN_REDIS_HOST","CFN_REDIS_PORT","safeEnvVars","undefined","ANTHROPIC_API_KEY","match","AGENT_TYPE","TASK_ID","ITERATION","CONTEXT","MODE","PRIORITY","PARENT_TASK_ID","EPIC_CONTEXT","PHASE_CONTEXT","SUCCESS_CRITERIA","join","agentProcess","stdio","cwd","on","code","signal","exit","err","message","kill","buildTaskDescription","desc","main","argv","includes","isMainModule","url","endsWith","replace","catch"],"mappings":"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"}
|
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Spawner Module
|
|
3
|
+
*
|
|
4
|
+
* High-level API for spawning agents with full type safety,
|
|
5
|
+
* environment variable handling, provider configuration parsing,
|
|
6
|
+
* and Redis coordination integration.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const spawner = new AgentSpawner();
|
|
10
|
+
* const result = await spawner.spawnAgent({
|
|
11
|
+
* agentType: 'backend-developer',
|
|
12
|
+
* taskId: 'task-123',
|
|
13
|
+
* iteration: 1,
|
|
14
|
+
* mode: 'standard'
|
|
15
|
+
* });
|
|
16
|
+
*/ import { existsSync, readFileSync } from 'fs';
|
|
17
|
+
import { resolve } from 'path';
|
|
18
|
+
import { spawn as childSpawn } from 'child_process';
|
|
19
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
20
|
+
import { getEnvValue, getNetworkName } from '../lib/environment-contract';
|
|
21
|
+
/**
|
|
22
|
+
* AgentSpawner class - Type-safe agent spawning with validation
|
|
23
|
+
*/ export class AgentSpawner {
|
|
24
|
+
projectRoot;
|
|
25
|
+
agentProfilesDir;
|
|
26
|
+
agentConfigFile;
|
|
27
|
+
constructor(projectRoot){
|
|
28
|
+
this.projectRoot = projectRoot || process.cwd();
|
|
29
|
+
this.agentProfilesDir = resolve(this.projectRoot, '.claude/agents/cfn-dev-team');
|
|
30
|
+
this.agentConfigFile = resolve(this.projectRoot, '.claude/cfn-config/team-providers.json');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Spawn an agent with the given configuration
|
|
34
|
+
*/ async spawnAgent(config) {
|
|
35
|
+
const timestamp = new Date().toISOString();
|
|
36
|
+
const agentId = this.generateAgentId(config.agentType);
|
|
37
|
+
try {
|
|
38
|
+
// Validate configuration
|
|
39
|
+
this.validateSpawnConfig(config);
|
|
40
|
+
// Check agent exists
|
|
41
|
+
const agentExists = await this.validateAgentExists(config.agentType);
|
|
42
|
+
if (!agentExists) {
|
|
43
|
+
return {
|
|
44
|
+
agentId,
|
|
45
|
+
pid: -1,
|
|
46
|
+
status: 'failed',
|
|
47
|
+
timestamp,
|
|
48
|
+
error: `Agent type not found: ${config.agentType}`
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Parse provider configuration if not explicitly provided
|
|
52
|
+
let provider = config.provider;
|
|
53
|
+
let model = config.model;
|
|
54
|
+
if (!provider || !model) {
|
|
55
|
+
const providerConfig = await this.parseAgentProvider(config.agentType);
|
|
56
|
+
provider = provider || providerConfig.provider;
|
|
57
|
+
model = model || providerConfig.model;
|
|
58
|
+
}
|
|
59
|
+
// Build environment variables
|
|
60
|
+
const env = this.buildEnvironment(config, agentId, provider, model);
|
|
61
|
+
// Spawn the process
|
|
62
|
+
const pid = await this.spawnProcess(config.agentType, env, config.background);
|
|
63
|
+
return {
|
|
64
|
+
agentId,
|
|
65
|
+
pid,
|
|
66
|
+
status: 'spawned',
|
|
67
|
+
timestamp,
|
|
68
|
+
metadata: {
|
|
69
|
+
agentType: config.agentType,
|
|
70
|
+
taskId: config.taskId,
|
|
71
|
+
iteration: config.iteration,
|
|
72
|
+
mode: config.mode,
|
|
73
|
+
provider,
|
|
74
|
+
model
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
agentId,
|
|
80
|
+
pid: -1,
|
|
81
|
+
status: 'failed',
|
|
82
|
+
timestamp,
|
|
83
|
+
error: error instanceof Error ? error.message : String(error)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Spawn a worker with team configuration
|
|
89
|
+
*/ async spawnWorker(config) {
|
|
90
|
+
const timestamp = new Date().toISOString();
|
|
91
|
+
const workerId = this.generateWorkerId(config.team);
|
|
92
|
+
try {
|
|
93
|
+
// Validate worker configuration
|
|
94
|
+
this.validateWorkerConfig(config);
|
|
95
|
+
// Load team provider configuration
|
|
96
|
+
const teamConfig = this.loadTeamConfig(config.team);
|
|
97
|
+
// Select model based on complexity
|
|
98
|
+
const model = this.selectModel(config.team, config.complexity);
|
|
99
|
+
// Get API key from environment
|
|
100
|
+
const apiKey = this.getApiKey(config.team, 'workers');
|
|
101
|
+
// Build environment for worker
|
|
102
|
+
const env = this.buildWorkerEnvironment(config, workerId, model, apiKey);
|
|
103
|
+
// Provider routing
|
|
104
|
+
this.routeWorkerProvider(config.providerMode, config.team, model, apiKey);
|
|
105
|
+
return {
|
|
106
|
+
agentId: workerId,
|
|
107
|
+
pid: 0,
|
|
108
|
+
status: 'spawned',
|
|
109
|
+
timestamp,
|
|
110
|
+
metadata: {
|
|
111
|
+
team: config.team,
|
|
112
|
+
complexity: config.complexity,
|
|
113
|
+
model,
|
|
114
|
+
provider: config.providerMode
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
} catch (error) {
|
|
118
|
+
return {
|
|
119
|
+
agentId: workerId,
|
|
120
|
+
pid: -1,
|
|
121
|
+
status: 'failed',
|
|
122
|
+
timestamp,
|
|
123
|
+
error: error instanceof Error ? error.message : String(error)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Validate that an agent type exists in the profiles directory
|
|
129
|
+
*/ async validateAgentExists(agentType) {
|
|
130
|
+
// Normalize agent type (handle both underscore and hyphen variations)
|
|
131
|
+
const normalized = agentType.replace(/_/g, '-').toLowerCase();
|
|
132
|
+
// Check for agent profile in subdirectories
|
|
133
|
+
const possiblePaths = [
|
|
134
|
+
resolve(this.agentProfilesDir, `${normalized}.md`),
|
|
135
|
+
// Check in subdirectories
|
|
136
|
+
...this.findAgentInSubdirs(normalized)
|
|
137
|
+
];
|
|
138
|
+
return possiblePaths.some((path)=>existsSync(path));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Parse provider configuration from agent profile frontmatter
|
|
142
|
+
*/ async parseAgentProvider(agentType) {
|
|
143
|
+
const agentPath = this.findAgentProfile(agentType);
|
|
144
|
+
if (!agentPath) {
|
|
145
|
+
return {
|
|
146
|
+
provider: 'zai',
|
|
147
|
+
model: 'glm-4.6'
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const content = readFileSync(agentPath, 'utf-8');
|
|
152
|
+
const providerMatch = content.match(/<!-- PROVIDER_PARAMETERS\s*([\s\S]*?)\s*-->/);
|
|
153
|
+
if (providerMatch) {
|
|
154
|
+
const params = providerMatch[1];
|
|
155
|
+
const providerMatch_ = params.match(/provider:\s*(\w+)/);
|
|
156
|
+
const modelMatch = params.match(/model:\s*([^\n]+)/);
|
|
157
|
+
return {
|
|
158
|
+
provider: providerMatch_?.[1] || 'zai',
|
|
159
|
+
model: modelMatch?.[1]?.trim() || 'glm-4.6'
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
} catch (error) {
|
|
163
|
+
// Silent fallback
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
provider: 'zai',
|
|
167
|
+
model: 'glm-4.6'
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Generate a unique agent ID
|
|
172
|
+
*/ generateAgentId(agentType) {
|
|
173
|
+
const timestamp = Date.now();
|
|
174
|
+
const random = Math.random().toString(36).substring(2, 9);
|
|
175
|
+
return `agent-${agentType}-${timestamp}-${random}`;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Generate a unique worker ID
|
|
179
|
+
*/ generateWorkerId(team) {
|
|
180
|
+
const uuid = uuidv4().substring(0, 8);
|
|
181
|
+
return `worker-${team}-${uuid}`;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Validate spawn configuration
|
|
185
|
+
*/ validateSpawnConfig(config) {
|
|
186
|
+
const errors = [];
|
|
187
|
+
if (!config.agentType || typeof config.agentType !== 'string') {
|
|
188
|
+
errors.push('agentType must be a non-empty string');
|
|
189
|
+
}
|
|
190
|
+
if (!config.taskId || typeof config.taskId !== 'string') {
|
|
191
|
+
errors.push('taskId must be a non-empty string');
|
|
192
|
+
} else {
|
|
193
|
+
const taskIdValidation = this.validateTaskId(config.taskId);
|
|
194
|
+
if (!taskIdValidation.valid) {
|
|
195
|
+
errors.push(taskIdValidation.error || 'Invalid taskId format');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (config.iteration === undefined || typeof config.iteration !== 'number') {
|
|
199
|
+
errors.push('iteration must be a number');
|
|
200
|
+
}
|
|
201
|
+
if (![
|
|
202
|
+
'mvp',
|
|
203
|
+
'standard',
|
|
204
|
+
'enterprise'
|
|
205
|
+
].includes(config.mode)) {
|
|
206
|
+
errors.push('mode must be mvp, standard, or enterprise');
|
|
207
|
+
}
|
|
208
|
+
if (errors.length > 0) {
|
|
209
|
+
throw new Error(`Configuration validation failed:\n${errors.join('\n')}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Validate worker configuration
|
|
214
|
+
*/ validateWorkerConfig(config) {
|
|
215
|
+
const errors = [];
|
|
216
|
+
if (!config.team || typeof config.team !== 'string') {
|
|
217
|
+
errors.push('team must be a non-empty string');
|
|
218
|
+
}
|
|
219
|
+
if (![
|
|
220
|
+
'simple',
|
|
221
|
+
'complex'
|
|
222
|
+
].includes(config.complexity)) {
|
|
223
|
+
errors.push('complexity must be simple or complex');
|
|
224
|
+
}
|
|
225
|
+
if (![
|
|
226
|
+
'auto',
|
|
227
|
+
'zai',
|
|
228
|
+
'anthropic'
|
|
229
|
+
].includes(config.providerMode)) {
|
|
230
|
+
errors.push('providerMode must be auto, zai, or anthropic');
|
|
231
|
+
}
|
|
232
|
+
if (errors.length > 0) {
|
|
233
|
+
throw new Error(`Worker configuration validation failed:\n${errors.join('\n')}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Validate task ID format (CVSS 8.9 - command injection prevention)
|
|
238
|
+
* Supports both raw IDs and Phase 1 prefixed IDs (cli:*, trigger:*)
|
|
239
|
+
* Pattern: alphanumeric, underscore, hyphen, dot, and colon (for mode prefix) only, max 128 chars
|
|
240
|
+
*
|
|
241
|
+
* Accepted formats:
|
|
242
|
+
* - Raw: task-123 (16 chars)
|
|
243
|
+
* - Prefixed: cli:task-123 (20 chars)
|
|
244
|
+
* - Prefixed: trigger:task-123 (24 chars)
|
|
245
|
+
*/ validateTaskId(taskId) {
|
|
246
|
+
if (typeof taskId !== 'string' || taskId.length === 0) {
|
|
247
|
+
return {
|
|
248
|
+
valid: false,
|
|
249
|
+
error: 'Task ID must be a non-empty string'
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
// Updated pattern to support namespace prefixes (e.g., cli:, trigger:, task:, orchestrator:)
|
|
253
|
+
const taskIdPattern = /^([a-z]+:)?[a-zA-Z0-9_.-]{1,64}$/;
|
|
254
|
+
if (!taskIdPattern.test(taskId)) {
|
|
255
|
+
return {
|
|
256
|
+
valid: false,
|
|
257
|
+
error: 'Invalid task ID format - must contain optional namespace prefix (e.g., "cli:") and alphanumeric characters, dot, underscore, hyphens (max 64 chars)'
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
valid: true
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Build environment variables for agent execution
|
|
266
|
+
*
|
|
267
|
+
* Provider routing: Sets both PROVIDER and CLAUDE_API_PROVIDER for compatibility.
|
|
268
|
+
* - PROVIDER: New convention used by agent-spawner
|
|
269
|
+
* - CLAUDE_API_PROVIDER: Legacy convention used by anthropic-client.ts getAPIConfig()
|
|
270
|
+
*
|
|
271
|
+
* BUG FIX: Previously only set PROVIDER, but anthropic-client.ts checked CLAUDE_API_PROVIDER
|
|
272
|
+
*/ buildEnvironment(config, agentId, provider, model) {
|
|
273
|
+
const env = {
|
|
274
|
+
...process.env,
|
|
275
|
+
AGENT_ID: agentId,
|
|
276
|
+
AGENT_TYPE: config.agentType,
|
|
277
|
+
TASK_ID: config.taskId,
|
|
278
|
+
ITERATION: String(config.iteration),
|
|
279
|
+
MODE: config.mode,
|
|
280
|
+
// Provider routing - set both for compatibility
|
|
281
|
+
PROVIDER: provider,
|
|
282
|
+
CLAUDE_API_PROVIDER: provider,
|
|
283
|
+
MODEL: model,
|
|
284
|
+
SPAWNED_AT: new Date().toISOString(),
|
|
285
|
+
PROJECT_ROOT: this.projectRoot,
|
|
286
|
+
// Redis coordination for CLI mode agents (resolved via environment contract)
|
|
287
|
+
CFN_REDIS_HOST: getEnvValue('redis_host', 'cli'),
|
|
288
|
+
CFN_REDIS_PORT: getEnvValue('redis_port', 'cli'),
|
|
289
|
+
// FIX: Don't use REDIS_PASSWORD from parent env - only explicit CFN_REDIS_PASSWORD
|
|
290
|
+
// This prevents CLI agents from inheriting the wrong password from shell environment
|
|
291
|
+
CFN_REDIS_PASSWORD: process.env.CFN_REDIS_PASSWORD || '',
|
|
292
|
+
CFN_NETWORK_NAME: getNetworkName('cli')
|
|
293
|
+
};
|
|
294
|
+
// Add provider-specific API keys if available
|
|
295
|
+
// This ensures spawned agents have access to the correct API key for their provider
|
|
296
|
+
if (provider === 'zai' && process.env.ZAI_API_KEY) {
|
|
297
|
+
env.ZAI_API_KEY = process.env.ZAI_API_KEY;
|
|
298
|
+
}
|
|
299
|
+
if (provider === 'kimi' && process.env.KIMI_API_KEY) {
|
|
300
|
+
env.KIMI_API_KEY = process.env.KIMI_API_KEY;
|
|
301
|
+
}
|
|
302
|
+
if (provider === 'openrouter' && process.env.OPENROUTER_API_KEY) {
|
|
303
|
+
env.OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY;
|
|
304
|
+
}
|
|
305
|
+
if (provider === 'anthropic' && process.env.ANTHROPIC_API_KEY) {
|
|
306
|
+
env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
|
307
|
+
}
|
|
308
|
+
// Add optional prompt parameter if provided
|
|
309
|
+
if (config.prompt) {
|
|
310
|
+
env.PROMPT = config.prompt;
|
|
311
|
+
}
|
|
312
|
+
// Merge user-provided environment variables
|
|
313
|
+
if (config.env) {
|
|
314
|
+
Object.assign(env, config.env);
|
|
315
|
+
}
|
|
316
|
+
// Debug logging for provider routing
|
|
317
|
+
console.error(`[agent-spawner] Building env for agent ${agentId}:`);
|
|
318
|
+
console.error(`[agent-spawner] PROVIDER=${provider}, CLAUDE_API_PROVIDER=${provider}`);
|
|
319
|
+
console.error(`[agent-spawner] Has ZAI_API_KEY: ${!!env.ZAI_API_KEY}`);
|
|
320
|
+
console.error(`[agent-spawner] Has KIMI_API_KEY: ${!!env.KIMI_API_KEY}`);
|
|
321
|
+
console.error(`[agent-spawner] Has ANTHROPIC_API_KEY: ${!!env.ANTHROPIC_API_KEY}`);
|
|
322
|
+
return env;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Build environment for worker process
|
|
326
|
+
*/ buildWorkerEnvironment(config, workerId, model, apiKey) {
|
|
327
|
+
const env = {
|
|
328
|
+
...process.env,
|
|
329
|
+
WORKER_ID: workerId,
|
|
330
|
+
TEAM: config.team,
|
|
331
|
+
COMPLEXITY: config.complexity,
|
|
332
|
+
MODEL: model,
|
|
333
|
+
API_KEY: apiKey,
|
|
334
|
+
PROJECT_ROOT: this.projectRoot
|
|
335
|
+
};
|
|
336
|
+
if (config.agentType) {
|
|
337
|
+
env.AGENT_TYPE = config.agentType;
|
|
338
|
+
}
|
|
339
|
+
if (config.taskContext) {
|
|
340
|
+
env.TASK_CONTEXT = config.taskContext;
|
|
341
|
+
}
|
|
342
|
+
return env;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Spawn the actual process
|
|
346
|
+
*/ async spawnProcess(agentType, env, background = true) {
|
|
347
|
+
const args = [
|
|
348
|
+
'src/cli/agent-executor.ts',
|
|
349
|
+
'--agent-type',
|
|
350
|
+
agentType
|
|
351
|
+
];
|
|
352
|
+
const child = childSpawn('tsx', args, {
|
|
353
|
+
env,
|
|
354
|
+
stdio: background ? 'ignore' : 'inherit',
|
|
355
|
+
detached: background
|
|
356
|
+
});
|
|
357
|
+
const pid = child.pid || 0;
|
|
358
|
+
if (background) {
|
|
359
|
+
child.unref();
|
|
360
|
+
} else {
|
|
361
|
+
await new Promise((resolve, reject)=>{
|
|
362
|
+
child.on('exit', (code)=>{
|
|
363
|
+
if (code !== 0) {
|
|
364
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
365
|
+
} else {
|
|
366
|
+
resolve(undefined);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
return pid;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Find agent profile in directory structure
|
|
375
|
+
*/ findAgentProfile(agentType) {
|
|
376
|
+
const normalized = agentType.replace(/_/g, '-').toLowerCase();
|
|
377
|
+
// Direct path
|
|
378
|
+
const directPath = resolve(this.agentProfilesDir, `${normalized}.md`);
|
|
379
|
+
if (existsSync(directPath)) {
|
|
380
|
+
return directPath;
|
|
381
|
+
}
|
|
382
|
+
// Search in subdirectories
|
|
383
|
+
const subdirs = [
|
|
384
|
+
'developers',
|
|
385
|
+
'testers',
|
|
386
|
+
'reviewers',
|
|
387
|
+
'architecture',
|
|
388
|
+
'dev-ops',
|
|
389
|
+
'product-owners',
|
|
390
|
+
'coordinators',
|
|
391
|
+
'analysts',
|
|
392
|
+
'utility'
|
|
393
|
+
];
|
|
394
|
+
for (const subdir of subdirs){
|
|
395
|
+
const path = resolve(this.agentProfilesDir, subdir, `${normalized}.md`);
|
|
396
|
+
if (existsSync(path)) {
|
|
397
|
+
return path;
|
|
398
|
+
}
|
|
399
|
+
// Check nested subdirectories
|
|
400
|
+
const nestedDirs = [
|
|
401
|
+
'frontend',
|
|
402
|
+
'backend',
|
|
403
|
+
'database',
|
|
404
|
+
'quality',
|
|
405
|
+
'e2e',
|
|
406
|
+
'unit',
|
|
407
|
+
'validation',
|
|
408
|
+
'data'
|
|
409
|
+
];
|
|
410
|
+
for (const nested of nestedDirs){
|
|
411
|
+
const nestedPath = resolve(this.agentProfilesDir, subdir, nested, `${normalized}.md`);
|
|
412
|
+
if (existsSync(nestedPath)) {
|
|
413
|
+
return nestedPath;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Find agent in subdirectories
|
|
421
|
+
*/ findAgentInSubdirs(normalized) {
|
|
422
|
+
const paths = [];
|
|
423
|
+
const subdirs = [
|
|
424
|
+
'developers',
|
|
425
|
+
'testers',
|
|
426
|
+
'reviewers',
|
|
427
|
+
'architecture',
|
|
428
|
+
'dev-ops',
|
|
429
|
+
'product-owners',
|
|
430
|
+
'coordinators',
|
|
431
|
+
'analysts',
|
|
432
|
+
'utility'
|
|
433
|
+
];
|
|
434
|
+
for (const subdir of subdirs){
|
|
435
|
+
const path = resolve(this.agentProfilesDir, subdir, `${normalized}.md`);
|
|
436
|
+
paths.push(path);
|
|
437
|
+
// Check nested directories
|
|
438
|
+
const nestedDirs = [
|
|
439
|
+
'frontend',
|
|
440
|
+
'backend',
|
|
441
|
+
'database',
|
|
442
|
+
'quality',
|
|
443
|
+
'e2e',
|
|
444
|
+
'unit',
|
|
445
|
+
'validation',
|
|
446
|
+
'data'
|
|
447
|
+
];
|
|
448
|
+
for (const nested of nestedDirs){
|
|
449
|
+
paths.push(resolve(this.agentProfilesDir, subdir, nested, `${normalized}.md`));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return paths;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Load team configuration from config file
|
|
456
|
+
*/ loadTeamConfig(team) {
|
|
457
|
+
if (!existsSync(this.agentConfigFile)) {
|
|
458
|
+
throw new Error(`Team configuration not found at ${this.agentConfigFile}`);
|
|
459
|
+
}
|
|
460
|
+
const content = readFileSync(this.agentConfigFile, 'utf-8');
|
|
461
|
+
const config = JSON.parse(content);
|
|
462
|
+
if (!config.teams || !config.teams[team]) {
|
|
463
|
+
throw new Error(`Invalid or missing provider configuration for team: ${team}`);
|
|
464
|
+
}
|
|
465
|
+
return config.teams[team];
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Select model based on complexity
|
|
469
|
+
*/ selectModel(team, complexity) {
|
|
470
|
+
const config = this.loadTeamConfig(team);
|
|
471
|
+
const workers = config.workers;
|
|
472
|
+
const models = workers?.models;
|
|
473
|
+
if (models && models[complexity]) {
|
|
474
|
+
return models[complexity];
|
|
475
|
+
}
|
|
476
|
+
// Fallback to default complexity
|
|
477
|
+
const defaultComplexity = 'simple';
|
|
478
|
+
if (models && models[defaultComplexity]) {
|
|
479
|
+
return models[defaultComplexity];
|
|
480
|
+
}
|
|
481
|
+
return 'gpt-4';
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Get API key from environment
|
|
485
|
+
*/ getApiKey(team, role) {
|
|
486
|
+
const config = this.loadTeamConfig(team);
|
|
487
|
+
const roleConfig = config[role];
|
|
488
|
+
if (!roleConfig) {
|
|
489
|
+
throw new Error(`No configuration found for team=${team}, role=${role}`);
|
|
490
|
+
}
|
|
491
|
+
const apiKeyEnvVar = roleConfig.apiKeyEnvVar;
|
|
492
|
+
if (!apiKeyEnvVar) {
|
|
493
|
+
throw new Error(`apiKeyEnvVar not configured for team=${team}, role=${role}`);
|
|
494
|
+
}
|
|
495
|
+
const apiKey = process.env[apiKeyEnvVar];
|
|
496
|
+
if (!apiKey) {
|
|
497
|
+
throw new Error(`API key not found in environment variable: ${apiKeyEnvVar}`);
|
|
498
|
+
}
|
|
499
|
+
return apiKey;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Route worker to appropriate provider
|
|
503
|
+
*/ routeWorkerProvider(providerMode, team, model, apiKey) {
|
|
504
|
+
const config = this.loadTeamConfig(team);
|
|
505
|
+
const workers = config.workers;
|
|
506
|
+
const provider = workers?.provider;
|
|
507
|
+
const baseUrl = workers?.baseUrl;
|
|
508
|
+
switch(providerMode){
|
|
509
|
+
case 'auto':
|
|
510
|
+
this.routeAutoProvider(provider, baseUrl, model, apiKey);
|
|
511
|
+
break;
|
|
512
|
+
case 'zai':
|
|
513
|
+
process.env.ZAI_API_KEY = apiKey;
|
|
514
|
+
process.env.ZAI_BASE_URL = baseUrl;
|
|
515
|
+
process.env.ZAI_MODEL = model;
|
|
516
|
+
break;
|
|
517
|
+
case 'anthropic':
|
|
518
|
+
process.env.ANTHROPIC_API_KEY = apiKey;
|
|
519
|
+
process.env.ANTHROPIC_BASE_URL = baseUrl;
|
|
520
|
+
process.env.ANTHROPIC_MODEL = model;
|
|
521
|
+
break;
|
|
522
|
+
default:
|
|
523
|
+
throw new Error(`Invalid provider mode: ${providerMode}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Route to appropriate provider based on configuration
|
|
528
|
+
*/ routeAutoProvider(provider, baseUrl, model, apiKey) {
|
|
529
|
+
switch(provider){
|
|
530
|
+
case 'zai':
|
|
531
|
+
process.env.ZAI_API_KEY = apiKey;
|
|
532
|
+
process.env.ZAI_BASE_URL = baseUrl;
|
|
533
|
+
process.env.ZAI_MODEL = model;
|
|
534
|
+
break;
|
|
535
|
+
case 'anthropic':
|
|
536
|
+
process.env.ANTHROPIC_API_KEY = apiKey;
|
|
537
|
+
process.env.ANTHROPIC_BASE_URL = baseUrl;
|
|
538
|
+
process.env.ANTHROPIC_MODEL = model;
|
|
539
|
+
break;
|
|
540
|
+
default:
|
|
541
|
+
throw new Error(`Unsupported provider: ${provider}`);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
//# sourceMappingURL=agent-spawner.js.map
|