claude-flow-novice 2.15.3 → 2.15.4
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/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/.claude/commands/cfn-loop-cli.md +16 -2
- package/.claude/commands/switch-api.md +31 -10
- package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
- package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
- package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
- package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/.claude/skills/cfn-redis-coordination/get-context.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
- package/README.md +116 -475
- package/claude-assets/agents/cfn-dev-team/README.md +103 -0
- package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
- package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
- 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 +828 -0
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/claude-assets/commands/cfn-loop-cli.md +16 -2
- package/claude-assets/commands/switch-api.md +31 -10
- package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
- package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
- package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
- package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
- package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +84 -113
- package/claude-assets/skills/agent-lifecycle/simple-audit.sh +33 -6
- package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
- package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
- package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
- package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
- package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
- package/claude-assets/skills/bootstrap/database-connection.md +464 -0
- package/claude-assets/skills/bootstrap/error-handling.md +580 -0
- package/claude-assets/skills/bootstrap/file-operations.md +699 -0
- package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
- package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
- package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
- package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
- package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
- package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
- package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
- package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
- package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
- package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
- package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
- package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
- package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
- package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
- package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
- package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
- package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
- package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
- package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/claude-assets/skills/cfn-redis-coordination/get-context.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
- package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
- package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
- package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
- package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
- package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
- package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
- package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
- package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
- package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
- package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
- package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
- package/claude-assets/skills/cfn-utilities/test.sh +317 -0
- package/claude-assets/skills/integration/agent-handoff.sh +62 -64
- package/claude-assets/skills/json-validation/SKILL.md +431 -0
- package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
- package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
- package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
- package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
- package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
- package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
- package/claude-assets/skills/workflow-codification/test-integration.sh +15 -0
- package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh +55 -14
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
- package/claude-assets/skills/workflow-codification/track-edge-case.sh +27 -60
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/ace/ace-curator.js +10 -2
- package/dist/ace/ace-curator.js.map +1 -1
- package/dist/ace/ace-generator.js +4 -0
- package/dist/ace/ace-generator.js.map +1 -1
- package/dist/ace/ace-reflector.js +1 -1
- package/dist/ace/ace-reflector.js.map +1 -1
- package/dist/ace/context-injection.js +24 -2
- package/dist/ace/context-injection.js.map +1 -1
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/agents/task-agent-integration.js +1 -1
- package/dist/agents/task-agent-integration.js.map +1 -1
- package/dist/api/health-endpoints.js +390 -0
- package/dist/api/health-endpoints.js.map +1 -0
- package/dist/cli/agent-executor.js +4 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +89 -1
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +130 -37
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/skill-cache-validator.js +412 -0
- package/dist/cli/skill-cache-validator.js.map +1 -0
- package/dist/cli/skill-cli.js +991 -0
- package/dist/cli/skill-cli.js.map +1 -0
- package/dist/cli/skill-execution-logger.js +284 -0
- package/dist/cli/skill-execution-logger.js.map +1 -0
- package/dist/cli/skill-loader.js +457 -0
- package/dist/cli/skill-loader.js.map +1 -0
- package/dist/coordination/event-bus.js +2 -2
- package/dist/coordination/event-bus.js.map +1 -1
- package/dist/coordination/fleet-manager.js +1 -1
- package/dist/coordination/fleet-manager.js.map +1 -1
- package/dist/coordination/index.js +23 -9
- package/dist/coordination/index.js.map +1 -1
- package/dist/coordination/types/fleet-manager.types.js.map +1 -1
- package/dist/db/migration-manager.js +483 -0
- package/dist/db/migration-manager.js.map +1 -0
- package/dist/db/skills-query.js +535 -0
- package/dist/db/skills-query.js.map +1 -0
- package/dist/integration/DatabaseHandoff.js +1 -1
- package/dist/integration/DatabaseHandoff.js.map +1 -1
- package/dist/jobs/edge-case-analyzer.js +367 -0
- package/dist/jobs/edge-case-analyzer.js.map +1 -0
- package/dist/jobs/promotion-sla-enforcer.js +288 -0
- package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
- package/dist/lib/agent-output-parser.js.map +1 -1
- package/dist/lib/agent-output-validator.js.map +1 -1
- package/dist/lib/agent-workspace.js +281 -0
- package/dist/lib/agent-workspace.js.map +1 -0
- package/dist/lib/atomic-file-writer.js +377 -0
- package/dist/lib/atomic-file-writer.js.map +1 -0
- package/dist/lib/backup-manager.js +779 -0
- package/dist/lib/backup-manager.js.map +1 -0
- package/dist/lib/checkpoint-manager.js +837 -0
- package/dist/lib/checkpoint-manager.js.map +1 -0
- package/dist/lib/circuit-breaker.js +340 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/completion-signal-handler.js +243 -0
- package/dist/lib/completion-signal-handler.js.map +1 -0
- package/dist/lib/config-manager.js +312 -0
- package/dist/lib/config-manager.js.map +1 -0
- package/dist/lib/config-migrator.js +386 -0
- package/dist/lib/config-migrator.js.map +1 -0
- package/dist/lib/config-validator.js.map +1 -1
- package/dist/lib/correlation-cache.js +311 -0
- package/dist/lib/correlation-cache.js.map +1 -0
- package/dist/lib/correlation.js +263 -0
- package/dist/lib/correlation.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +520 -0
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
- package/dist/lib/database-service/correlation.js +329 -0
- package/dist/lib/database-service/correlation.js.map +1 -0
- package/dist/lib/database-service/errors.js +120 -0
- package/dist/lib/database-service/errors.js.map +1 -0
- package/dist/lib/database-service/index.js +168 -0
- package/dist/lib/database-service/index.js.map +1 -0
- package/dist/lib/database-service/postgres-adapter.js +526 -0
- package/dist/lib/database-service/postgres-adapter.js.map +1 -0
- package/dist/lib/database-service/redis-adapter.js +360 -0
- package/dist/lib/database-service/redis-adapter.js.map +1 -0
- package/dist/lib/database-service/sqlite-adapter.js +544 -0
- package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
- package/dist/lib/database-service/transaction-manager.js +773 -0
- package/dist/lib/database-service/transaction-manager.js.map +1 -0
- package/dist/lib/database-service/types.js +23 -0
- package/dist/lib/database-service/types.js.map +1 -0
- package/dist/lib/deadlock-resolver.js +292 -0
- package/dist/lib/deadlock-resolver.js.map +1 -0
- package/dist/lib/distributed-lock.js +451 -0
- package/dist/lib/distributed-lock.js.map +1 -0
- package/dist/lib/edge-case-deduplicator.js +227 -0
- package/dist/lib/edge-case-deduplicator.js.map +1 -0
- package/dist/lib/encryption-manager.js +322 -0
- package/dist/lib/encryption-manager.js.map +1 -0
- package/dist/lib/error-aggregator.js +234 -0
- package/dist/lib/error-aggregator.js.map +1 -0
- package/dist/lib/errors.js +287 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-lock-manager.js +578 -0
- package/dist/lib/file-lock-manager.js.map +1 -0
- package/dist/lib/file-operations.js +367 -0
- package/dist/lib/file-operations.js.map +1 -0
- package/dist/lib/idempotent-write.js +237 -0
- package/dist/lib/idempotent-write.js.map +1 -0
- package/dist/lib/integration-schema-validator.js +522 -0
- package/dist/lib/integration-schema-validator.js.map +1 -0
- package/dist/lib/lock-health-monitor.js +298 -0
- package/dist/lib/lock-health-monitor.js.map +1 -0
- package/dist/lib/log-shipper.js +422 -0
- package/dist/lib/log-shipper.js.map +1 -0
- package/dist/lib/logging.js +146 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/message-deduplicator.js +439 -0
- package/dist/lib/message-deduplicator.js.map +1 -0
- package/dist/lib/multi-system-query.js +604 -0
- package/dist/lib/multi-system-query.js.map +1 -0
- package/dist/lib/orphan-detector.js +332 -0
- package/dist/lib/orphan-detector.js.map +1 -0
- package/dist/lib/password-generator.js +166 -0
- package/dist/lib/password-generator.js.map +1 -0
- package/dist/lib/path-validator.js +429 -0
- package/dist/lib/path-validator.js.map +1 -0
- package/dist/lib/query-translator.js +905 -0
- package/dist/lib/query-translator.js.map +1 -0
- package/dist/lib/queue-recovery.js +469 -0
- package/dist/lib/queue-recovery.js.map +1 -0
- package/dist/lib/redis-queue-manager.js +512 -0
- package/dist/lib/redis-queue-manager.js.map +1 -0
- package/dist/lib/reflection-archiver.js +272 -0
- package/dist/lib/reflection-archiver.js.map +1 -0
- package/dist/lib/retry-manager.js +453 -0
- package/dist/lib/retry-manager.js.map +1 -0
- package/dist/lib/retry.js +262 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/schema-transform.js +695 -0
- package/dist/lib/schema-transform.js.map +1 -0
- package/dist/lib/schema-validator.js +491 -0
- package/dist/lib/schema-validator.js.map +1 -0
- package/dist/lib/skill-cache.js +297 -0
- package/dist/lib/skill-cache.js.map +1 -0
- package/dist/lib/skill-content-manager.js +337 -0
- package/dist/lib/skill-content-manager.js.map +1 -0
- package/dist/lib/skill-frontmatter-parser.js +237 -0
- package/dist/lib/skill-frontmatter-parser.js.map +1 -0
- package/dist/lib/skill-git-integration.js +275 -0
- package/dist/lib/skill-git-integration.js.map +1 -0
- package/dist/lib/skill-markdown-validator.js +396 -0
- package/dist/lib/skill-markdown-validator.js.map +1 -0
- package/dist/lib/skill-output-parser.js +312 -0
- package/dist/lib/skill-output-parser.js.map +1 -0
- package/dist/lib/unified-query-api.js +467 -0
- package/dist/lib/unified-query-api.js.map +1 -0
- package/dist/middleware/auth-middleware.js +350 -0
- package/dist/middleware/auth-middleware.js.map +1 -0
- package/dist/middleware/schema-validation.js +347 -0
- package/dist/middleware/schema-validation.js.map +1 -0
- package/dist/providers/anthropic-provider.js +1 -1
- package/dist/providers/anthropic-provider.js.map +1 -1
- package/dist/providers/provider-factory.js +2 -2
- package/dist/providers/provider-factory.js.map +1 -1
- package/dist/services/edge-case-analyzer.js +321 -0
- package/dist/services/edge-case-analyzer.js.map +1 -0
- package/dist/services/edge-case-deduplicator.js +266 -0
- package/dist/services/edge-case-deduplicator.js.map +1 -0
- package/dist/services/edge-case-detector.js +337 -0
- package/dist/services/edge-case-detector.js.map +1 -0
- package/dist/services/edge-case-tracker.js +547 -0
- package/dist/services/edge-case-tracker.js.map +1 -0
- package/dist/services/health-check-system.js +586 -0
- package/dist/services/health-check-system.js.map +1 -0
- package/dist/services/metrics-logger.js +412 -0
- package/dist/services/metrics-logger.js.map +1 -0
- package/dist/services/patch-generator.js +378 -0
- package/dist/services/patch-generator.js.map +1 -0
- package/dist/services/patch-validator.js +337 -0
- package/dist/services/patch-validator.js.map +1 -0
- package/dist/services/performance-monitor.js +811 -0
- package/dist/services/performance-monitor.js.map +1 -0
- package/dist/services/promotion-pipeline.js +918 -0
- package/dist/services/promotion-pipeline.js.map +1 -0
- package/dist/services/promotion-validator.js +394 -0
- package/dist/services/promotion-validator.js.map +1 -0
- package/dist/services/reflection-logger.js +388 -0
- package/dist/services/reflection-logger.js.map +1 -0
- package/dist/services/skill-deployment.js +472 -0
- package/dist/services/skill-deployment.js.map +1 -0
- package/dist/services/skill-loader.js +427 -0
- package/dist/services/skill-loader.js.map +1 -0
- package/dist/services/skill-promotion.js +372 -0
- package/dist/services/skill-promotion.js.map +1 -0
- package/dist/services/skill-validator.js +454 -0
- package/dist/services/skill-validator.js.map +1 -0
- package/dist/services/skill-versioning.js +244 -0
- package/dist/services/skill-versioning.js.map +1 -0
- package/dist/services/workspace-supervisor.js +597 -0
- package/dist/services/workspace-supervisor.js.map +1 -0
- package/dist/types/edge-case.js +45 -0
- package/dist/types/edge-case.js.map +1 -0
- package/package.json +201 -177
- package/readme/README.md +19 -4
- package/scripts/backup-cleanup.sh +627 -0
- package/scripts/cleanup-workspaces.sh +412 -0
- package/scripts/cleanup-yaml-configs.sh +141 -0
- package/scripts/deploy-approved-skills.sh +263 -0
- package/scripts/health-check.sh +447 -0
- package/scripts/log-aggregator.sh +554 -0
- package/scripts/log-monitor.sh +629 -0
- package/scripts/manage-agent-workspaces.sh +434 -0
- package/scripts/migrate-schema.sh +533 -0
- package/scripts/promote-staged-skills.sh +423 -0
- package/scripts/verify-no-secrets.sh +88 -35
- package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/.claude/skills/agent-lifecycle/SKILL.md +0 -60
- package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +0 -573
- package/.claude/skills/agent-lifecycle/simple-audit.sh +0 -31
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
- package/README.md.backup_before_replace +0 -781
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/agent-output-validator.ts"],"sourcesContent":["/**\r\n * Agent Output Validator\r\n * Zero-dependency validation library for CFN agent outputs\r\n *\r\n * @version 1.0.0\r\n * @description Type-safe validation with detailed error reporting\r\n */\r\n\r\nimport type {\r\n AgentOutput,\r\n Loop3Output,\r\n Loop2Output,\r\n ProductOwnerOutput,\r\n ValidationResult,\r\n ValidationError,\r\n Deliverable,\r\n Issue,\r\n Metrics,\r\n AgentError,\r\n AgentMetadata,\r\n DeliverableType,\r\n DeliverableStatus,\r\n IssueSeverity,\r\n IssueCategory,\r\n ValidationType,\r\n ProductOwnerDecision,\r\n CFNLoopMode,\r\n} from '../types/agent-output';\r\n\r\n// ============================================================================\r\n// Security Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Sanitize values for safe logging (prevents sensitive data leakage)\r\n * @param value - Value to sanitize\r\n * @param path - Field path for sensitive field detection\r\n * @returns Sanitized string representation\r\n */\r\nfunction sanitizeValue(value: unknown, path: string): string {\r\n // List of sensitive field patterns\r\n const sensitivePatterns = [\r\n 'password',\r\n 'passwd',\r\n 'pwd',\r\n 'token',\r\n 'key',\r\n 'secret',\r\n 'api_key',\r\n 'apikey',\r\n 'api-key',\r\n 'auth',\r\n 'credential',\r\n 'private',\r\n ];\r\n\r\n // Check if path contains sensitive field name\r\n const lowerPath = path.toLowerCase();\r\n const isSensitive = sensitivePatterns.some((pattern) =>\r\n lowerPath.includes(pattern)\r\n );\r\n\r\n if (isSensitive) {\r\n return '[REDACTED]';\r\n }\r\n\r\n // Sanitize value for safe display\r\n try {\r\n const str = JSON.stringify(value);\r\n\r\n // Truncate large values to prevent log flooding\r\n const maxLength = 100;\r\n if (str.length > maxLength) {\r\n return str.substring(0, maxLength) + '...[truncated]';\r\n }\r\n\r\n return str;\r\n } catch {\r\n // Handle circular references or non-serializable values\r\n return '[Non-serializable value]';\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Validation Class\r\n// ============================================================================\r\n\r\n/**\r\n * AgentOutputValidator: Main validation class\r\n * Provides schema validation, error reporting, and type checking\r\n */\r\nexport class AgentOutputValidator {\r\n /**\r\n * Validate agent output object\r\n */\r\n public validate(output: unknown): ValidationResult {\r\n const errors: ValidationError[] = [];\r\n const warnings: string[] = [];\r\n\r\n if (typeof output !== 'object' || output === null) {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'root',\r\n message: 'Agent output must be a valid JSON object',\r\n path: '/',\r\n code: 'INVALID_TYPE',\r\n },\r\n ],\r\n warnings,\r\n };\r\n }\r\n\r\n const obj = output as Record<string, unknown>;\r\n\r\n // Validate output_type discriminator\r\n const outputType = obj.output_type;\r\n if (\r\n outputType !== 'loop3' &&\r\n outputType !== 'loop2' &&\r\n outputType !== 'product_owner'\r\n ) {\r\n errors.push({\r\n field: 'output_type',\r\n message:\r\n \"output_type must be one of: 'loop3', 'loop2', 'product_owner'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: outputType,\r\n });\r\n return { valid: false, errors, warnings };\r\n }\r\n\r\n // Validate base fields common to all outputs\r\n this.validateBaseOutput(obj, errors);\r\n\r\n // Validate type-specific fields\r\n switch (outputType) {\r\n case 'loop3':\r\n this.validateLoop3Output(obj, errors, warnings);\r\n break;\r\n case 'loop2':\r\n this.validateLoop2Output(obj, errors, warnings);\r\n break;\r\n case 'product_owner':\r\n this.validateProductOwnerOutput(obj, errors, warnings);\r\n break;\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n warnings,\r\n output_type: outputType,\r\n };\r\n }\r\n\r\n /**\r\n * Validate JSON string\r\n */\r\n public validateJSON(jsonString: string): ValidationResult {\r\n try {\r\n const output = JSON.parse(jsonString);\r\n return this.validate(output);\r\n } catch (error) {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'json',\r\n message: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,\r\n path: 'root',\r\n code: 'JSON_PARSE_ERROR',\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Validate base output fields (common to all types)\r\n */\r\n private validateBaseOutput(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[]\r\n ): void {\r\n // Validate success (required boolean)\r\n if (typeof obj.success !== 'boolean') {\r\n errors.push({\r\n field: 'success',\r\n message: 'success must be a boolean',\r\n path: '/success',\r\n code: 'INVALID_TYPE',\r\n value: obj.success,\r\n });\r\n }\r\n\r\n // Validate confidence (required number 0.0-1.0)\r\n if (typeof obj.confidence !== 'number') {\r\n errors.push({\r\n field: 'confidence',\r\n message: 'confidence must be a number',\r\n path: '/confidence',\r\n code: 'INVALID_TYPE',\r\n value: obj.confidence,\r\n });\r\n } else if (obj.confidence < 0.0 || obj.confidence > 1.0) {\r\n errors.push({\r\n field: 'confidence',\r\n message: 'confidence must be between 0.0 and 1.0',\r\n path: '/confidence',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.confidence,\r\n });\r\n }\r\n\r\n // Validate iteration (required positive integer)\r\n if (typeof obj.iteration !== 'number') {\r\n errors.push({\r\n field: 'iteration',\r\n message: 'iteration must be a number',\r\n path: '/iteration',\r\n code: 'INVALID_TYPE',\r\n value: obj.iteration,\r\n });\r\n } else if (!Number.isInteger(obj.iteration) || obj.iteration < 1) {\r\n errors.push({\r\n field: 'iteration',\r\n message: 'iteration must be a positive integer',\r\n path: '/iteration',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.iteration,\r\n });\r\n }\r\n\r\n // Validate errors (required array)\r\n if (!Array.isArray(obj.errors)) {\r\n errors.push({\r\n field: 'errors',\r\n message: 'errors must be an array',\r\n path: '/errors',\r\n code: 'INVALID_TYPE',\r\n value: obj.errors,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.errors.length; i++) {\r\n this.validateError(obj.errors[i], i, errors);\r\n }\r\n }\r\n\r\n // Validate metadata (required object)\r\n if (typeof obj.metadata !== 'object' || obj.metadata === null) {\r\n errors.push({\r\n field: 'metadata',\r\n message: 'metadata must be an object',\r\n path: '/metadata',\r\n code: 'INVALID_TYPE',\r\n value: obj.metadata,\r\n });\r\n } else {\r\n this.validateMetadata(\r\n obj.metadata as Record<string, unknown>,\r\n errors\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Validate Loop 3 (Implementer) output\r\n */\r\n private validateLoop3Output(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[],\r\n warnings: string[]\r\n ): void {\r\n // Validate deliverables (required array)\r\n if (!Array.isArray(obj.deliverables)) {\r\n errors.push({\r\n field: 'deliverables',\r\n message: 'deliverables must be an array',\r\n path: '/deliverables',\r\n code: 'INVALID_TYPE',\r\n value: obj.deliverables,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.deliverables.length; i++) {\r\n this.validateDeliverable(obj.deliverables[i], i, errors);\r\n }\r\n\r\n if (obj.deliverables.length === 0) {\r\n warnings.push('Loop 3 output has no deliverables (empty array)');\r\n }\r\n }\r\n\r\n // Validate metrics (optional object)\r\n if (obj.metrics !== undefined) {\r\n if (typeof obj.metrics !== 'object' || obj.metrics === null) {\r\n errors.push({\r\n field: 'metrics',\r\n message: 'metrics must be an object',\r\n path: '/metrics',\r\n code: 'INVALID_TYPE',\r\n value: obj.metrics,\r\n });\r\n } else {\r\n this.validateMetrics(obj.metrics as Record<string, unknown>, errors);\r\n }\r\n }\r\n\r\n // Validate summary (optional string)\r\n if (obj.summary !== undefined && typeof obj.summary !== 'string') {\r\n errors.push({\r\n field: 'summary',\r\n message: 'summary must be a string',\r\n path: '/summary',\r\n code: 'INVALID_TYPE',\r\n value: obj.summary,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate Loop 2 (Validator) output\r\n */\r\n private validateLoop2Output(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[],\r\n warnings: string[]\r\n ): void {\r\n // Validate validation_type (required enum)\r\n const validationTypes: ValidationType[] = [\r\n 'review',\r\n 'test',\r\n 'security',\r\n 'architecture',\r\n 'performance',\r\n 'compliance',\r\n ];\r\n if (!validationTypes.includes(obj.validation_type as ValidationType)) {\r\n errors.push({\r\n field: 'validation_type',\r\n message: `validation_type must be one of: ${validationTypes.join(', ')}`,\r\n path: '/validation_type',\r\n code: 'INVALID_ENUM',\r\n value: obj.validation_type,\r\n });\r\n }\r\n\r\n // Validate issues (optional array, default to empty)\r\n if (obj.issues !== undefined) {\r\n if (!Array.isArray(obj.issues)) {\r\n errors.push({\r\n field: 'issues',\r\n message: 'issues must be an array',\r\n path: '/issues',\r\n code: 'INVALID_TYPE',\r\n value: obj.issues,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.issues.length; i++) {\r\n this.validateIssue(obj.issues[i], i, errors);\r\n }\r\n }\r\n }\r\n\r\n // Validate recommendations (optional array, default to empty)\r\n if (obj.recommendations !== undefined) {\r\n if (!Array.isArray(obj.recommendations)) {\r\n errors.push({\r\n field: 'recommendations',\r\n message: 'recommendations must be an array',\r\n path: '/recommendations',\r\n code: 'INVALID_TYPE',\r\n value: obj.recommendations,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.recommendations.length; i++) {\r\n if (typeof obj.recommendations[i] !== 'string') {\r\n errors.push({\r\n field: `recommendations[${i}]`,\r\n message: 'recommendation must be a string',\r\n path: `/recommendations/${i}`,\r\n code: 'INVALID_TYPE',\r\n value: obj.recommendations[i],\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Validate approved (required boolean)\r\n if (typeof obj.approved !== 'boolean') {\r\n errors.push({\r\n field: 'approved',\r\n message: 'approved must be a boolean',\r\n path: '/approved',\r\n code: 'INVALID_TYPE',\r\n value: obj.approved,\r\n });\r\n }\r\n\r\n // Validate summary (optional string)\r\n if (obj.summary !== undefined && typeof obj.summary !== 'string') {\r\n errors.push({\r\n field: 'summary',\r\n message: 'summary must be a string',\r\n path: '/summary',\r\n code: 'INVALID_TYPE',\r\n value: obj.summary,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate Product Owner output\r\n */\r\n private validateProductOwnerOutput(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[],\r\n warnings: string[]\r\n ): void {\r\n // Validate decision (required enum)\r\n const decisions: ProductOwnerDecision[] = [\r\n 'PROCEED',\r\n 'ITERATE',\r\n 'ABORT',\r\n ];\r\n if (!decisions.includes(obj.decision as ProductOwnerDecision)) {\r\n errors.push({\r\n field: 'decision',\r\n message: `decision must be one of: ${decisions.join(', ')}`,\r\n path: '/decision',\r\n code: 'INVALID_ENUM',\r\n value: obj.decision,\r\n });\r\n }\r\n\r\n // Validate rationale (required non-empty string)\r\n if (typeof obj.rationale !== 'string') {\r\n errors.push({\r\n field: 'rationale',\r\n message: 'rationale must be a string',\r\n path: '/rationale',\r\n code: 'INVALID_TYPE',\r\n value: obj.rationale,\r\n });\r\n } else if ((obj.rationale as string).length === 0) {\r\n errors.push({\r\n field: 'rationale',\r\n message: 'rationale must be a non-empty string',\r\n path: '/rationale',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.rationale,\r\n });\r\n }\r\n\r\n // Validate deliverables_validated (required boolean)\r\n if (typeof obj.deliverables_validated !== 'boolean') {\r\n errors.push({\r\n field: 'deliverables_validated',\r\n message: 'deliverables_validated must be a boolean',\r\n path: '/deliverables_validated',\r\n code: 'INVALID_TYPE',\r\n value: obj.deliverables_validated,\r\n });\r\n }\r\n\r\n // Validate next_action (required string)\r\n if (typeof obj.next_action !== 'string') {\r\n errors.push({\r\n field: 'next_action',\r\n message: 'next_action must be a string',\r\n path: '/next_action',\r\n code: 'INVALID_TYPE',\r\n value: obj.next_action,\r\n });\r\n }\r\n\r\n // Validate consensus_score (optional number 0.0-1.0)\r\n if (obj.consensus_score !== undefined) {\r\n if (typeof obj.consensus_score !== 'number') {\r\n errors.push({\r\n field: 'consensus_score',\r\n message: 'consensus_score must be a number',\r\n path: '/consensus_score',\r\n code: 'INVALID_TYPE',\r\n value: obj.consensus_score,\r\n });\r\n } else if (\r\n obj.consensus_score < 0.0 ||\r\n obj.consensus_score > 1.0\r\n ) {\r\n errors.push({\r\n field: 'consensus_score',\r\n message: 'consensus_score must be between 0.0 and 1.0',\r\n path: '/consensus_score',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.consensus_score,\r\n });\r\n }\r\n }\r\n\r\n // Validate gate_score (optional number 0.0-1.0)\r\n if (obj.gate_score !== undefined) {\r\n if (typeof obj.gate_score !== 'number') {\r\n errors.push({\r\n field: 'gate_score',\r\n message: 'gate_score must be a number',\r\n path: '/gate_score',\r\n code: 'INVALID_TYPE',\r\n value: obj.gate_score,\r\n });\r\n } else if (obj.gate_score < 0.0 || obj.gate_score > 1.0) {\r\n errors.push({\r\n field: 'gate_score',\r\n message: 'gate_score must be between 0.0 and 1.0',\r\n path: '/gate_score',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.gate_score,\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validate deliverable object\r\n */\r\n private validateDeliverable(\r\n deliverable: unknown,\r\n index: number,\r\n errors: ValidationError[]\r\n ): void {\r\n if (typeof deliverable !== 'object' || deliverable === null) {\r\n errors.push({\r\n field: `deliverables[${index}]`,\r\n message: 'deliverable must be an object',\r\n path: `/deliverables/${index}`,\r\n code: 'INVALID_TYPE',\r\n value: deliverable,\r\n });\r\n return;\r\n }\r\n\r\n const obj = deliverable as Record<string, unknown>;\r\n\r\n // Validate path (required non-empty string)\r\n if (typeof obj.path !== 'string' || obj.path.length === 0) {\r\n errors.push({\r\n field: `deliverables[${index}].path`,\r\n message: 'path must be a non-empty string',\r\n path: `/deliverables/${index}/path`,\r\n code: 'INVALID_TYPE',\r\n value: obj.path,\r\n });\r\n }\r\n\r\n // Validate type (required enum)\r\n const types: DeliverableType[] = [\r\n 'implementation',\r\n 'test',\r\n 'documentation',\r\n 'config',\r\n 'schema',\r\n 'script',\r\n 'other',\r\n ];\r\n if (!types.includes(obj.type as DeliverableType)) {\r\n errors.push({\r\n field: `deliverables[${index}].type`,\r\n message: `type must be one of: ${types.join(', ')}`,\r\n path: `/deliverables/${index}/type`,\r\n code: 'INVALID_ENUM',\r\n value: obj.type,\r\n });\r\n }\r\n\r\n // Validate status (required enum)\r\n const statuses: DeliverableStatus[] = [\r\n 'created',\r\n 'modified',\r\n 'deleted',\r\n 'validated',\r\n 'pending',\r\n ];\r\n if (!statuses.includes(obj.status as DeliverableStatus)) {\r\n errors.push({\r\n field: `deliverables[${index}].status`,\r\n message: `status must be one of: ${statuses.join(', ')}`,\r\n path: `/deliverables/${index}/status`,\r\n code: 'INVALID_ENUM',\r\n value: obj.status,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (\r\n obj.size_bytes !== undefined &&\r\n (typeof obj.size_bytes !== 'number' ||\r\n !Number.isInteger(obj.size_bytes) ||\r\n obj.size_bytes < 0)\r\n ) {\r\n errors.push({\r\n field: `deliverables[${index}].size_bytes`,\r\n message: 'size_bytes must be a non-negative integer',\r\n path: `/deliverables/${index}/size_bytes`,\r\n code: 'INVALID_TYPE',\r\n value: obj.size_bytes,\r\n });\r\n }\r\n\r\n if (\r\n obj.lines !== undefined &&\r\n (typeof obj.lines !== 'number' ||\r\n !Number.isInteger(obj.lines) ||\r\n obj.lines < 0)\r\n ) {\r\n errors.push({\r\n field: `deliverables[${index}].lines`,\r\n message: 'lines must be a non-negative integer',\r\n path: `/deliverables/${index}/lines`,\r\n code: 'INVALID_TYPE',\r\n value: obj.lines,\r\n });\r\n }\r\n\r\n if (obj.checksum !== undefined && typeof obj.checksum !== 'string') {\r\n errors.push({\r\n field: `deliverables[${index}].checksum`,\r\n message: 'checksum must be a string',\r\n path: `/deliverables/${index}/checksum`,\r\n code: 'INVALID_TYPE',\r\n value: obj.checksum,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate issue object\r\n */\r\n private validateIssue(\r\n issue: unknown,\r\n index: number,\r\n errors: ValidationError[]\r\n ): void {\r\n if (typeof issue !== 'object' || issue === null) {\r\n errors.push({\r\n field: `issues[${index}]`,\r\n message: 'issue must be an object',\r\n path: `/issues/${index}`,\r\n code: 'INVALID_TYPE',\r\n value: issue,\r\n });\r\n return;\r\n }\r\n\r\n const obj = issue as Record<string, unknown>;\r\n\r\n // Validate severity (required enum)\r\n const severities: IssueSeverity[] = [\r\n 'critical',\r\n 'high',\r\n 'medium',\r\n 'low',\r\n 'info',\r\n ];\r\n if (!severities.includes(obj.severity as IssueSeverity)) {\r\n errors.push({\r\n field: `issues[${index}].severity`,\r\n message: `severity must be one of: ${severities.join(', ')}`,\r\n path: `/issues/${index}/severity`,\r\n code: 'INVALID_ENUM',\r\n value: obj.severity,\r\n });\r\n }\r\n\r\n // Validate category (required enum)\r\n const categories: IssueCategory[] = [\r\n 'security',\r\n 'performance',\r\n 'quality',\r\n 'style',\r\n 'documentation',\r\n 'testing',\r\n 'architecture',\r\n 'other',\r\n ];\r\n if (!categories.includes(obj.category as IssueCategory)) {\r\n errors.push({\r\n field: `issues[${index}].category`,\r\n message: `category must be one of: ${categories.join(', ')}`,\r\n path: `/issues/${index}/category`,\r\n code: 'INVALID_ENUM',\r\n value: obj.category,\r\n });\r\n }\r\n\r\n // Validate message (required non-empty string)\r\n if (typeof obj.message !== 'string' || obj.message.length === 0) {\r\n errors.push({\r\n field: `issues[${index}].message`,\r\n message: 'message must be a non-empty string',\r\n path: `/issues/${index}/message`,\r\n code: 'INVALID_TYPE',\r\n value: obj.message,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (obj.location !== undefined && typeof obj.location !== 'string') {\r\n errors.push({\r\n field: `issues[${index}].location`,\r\n message: 'location must be a string',\r\n path: `/issues/${index}/location`,\r\n code: 'INVALID_TYPE',\r\n value: obj.location,\r\n });\r\n }\r\n\r\n if (\r\n obj.recommendation !== undefined &&\r\n typeof obj.recommendation !== 'string'\r\n ) {\r\n errors.push({\r\n field: `issues[${index}].recommendation`,\r\n message: 'recommendation must be a string',\r\n path: `/issues/${index}/recommendation`,\r\n code: 'INVALID_TYPE',\r\n value: obj.recommendation,\r\n });\r\n }\r\n\r\n if (obj.code !== undefined && typeof obj.code !== 'string') {\r\n errors.push({\r\n field: `issues[${index}].code`,\r\n message: 'code must be a string',\r\n path: `/issues/${index}/code`,\r\n code: 'INVALID_TYPE',\r\n value: obj.code,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate metrics object\r\n */\r\n private validateMetrics(\r\n metrics: Record<string, unknown>,\r\n errors: ValidationError[]\r\n ): void {\r\n // All metrics fields are optional numbers\r\n const knownMetrics = [\r\n 'files_created',\r\n 'files_modified',\r\n 'files_deleted',\r\n 'lines_of_code',\r\n 'test_coverage',\r\n 'tests_passed',\r\n 'tests_failed',\r\n 'execution_time_ms',\r\n 'memory_usage_mb',\r\n ];\r\n\r\n for (const key of knownMetrics) {\r\n if (metrics[key] !== undefined && typeof metrics[key] !== 'number') {\r\n errors.push({\r\n field: `metrics.${key}`,\r\n message: `${key} must be a number`,\r\n path: `/metrics/${key}`,\r\n code: 'INVALID_TYPE',\r\n value: metrics[key],\r\n });\r\n }\r\n }\r\n\r\n // Validate test_coverage range\r\n if (\r\n metrics.test_coverage !== undefined &&\r\n typeof metrics.test_coverage === 'number' &&\r\n (metrics.test_coverage < 0.0 || metrics.test_coverage > 1.0)\r\n ) {\r\n errors.push({\r\n field: 'metrics.test_coverage',\r\n message: 'test_coverage must be between 0.0 and 1.0',\r\n path: '/metrics/test_coverage',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: metrics.test_coverage,\r\n });\r\n }\r\n\r\n // Validate custom_metrics (if present)\r\n if (metrics.custom_metrics !== undefined) {\r\n if (\r\n typeof metrics.custom_metrics !== 'object' ||\r\n metrics.custom_metrics === null\r\n ) {\r\n errors.push({\r\n field: 'metrics.custom_metrics',\r\n message: 'custom_metrics must be an object',\r\n path: '/metrics/custom_metrics',\r\n code: 'INVALID_TYPE',\r\n value: metrics.custom_metrics,\r\n });\r\n } else {\r\n const customMetrics = metrics.custom_metrics as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(customMetrics)) {\r\n if (typeof value !== 'number') {\r\n errors.push({\r\n field: `metrics.custom_metrics.${key}`,\r\n message: `custom_metrics.${key} must be a number`,\r\n path: `/metrics/custom_metrics/${key}`,\r\n code: 'INVALID_TYPE',\r\n value,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Check for unknown fields (not in known metrics or custom_metrics)\r\n for (const key of Object.keys(metrics)) {\r\n if (key !== 'custom_metrics' && !knownMetrics.includes(key)) {\r\n errors.push({\r\n field: `metrics.${key}`,\r\n message: `Unknown metric field '${key}'. Use 'custom_metrics' for extensibility.`,\r\n path: `/metrics/${key}`,\r\n code: 'UNKNOWN_FIELD',\r\n value: metrics[key],\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validate error object\r\n */\r\n private validateError(\r\n error: unknown,\r\n index: number,\r\n errors: ValidationError[]\r\n ): void {\r\n if (typeof error !== 'object' || error === null) {\r\n errors.push({\r\n field: `errors[${index}]`,\r\n message: 'error must be an object',\r\n path: `/errors/${index}`,\r\n code: 'INVALID_TYPE',\r\n value: error,\r\n });\r\n return;\r\n }\r\n\r\n const obj = error as Record<string, unknown>;\r\n\r\n // Validate code (required string)\r\n if (typeof obj.code !== 'string') {\r\n errors.push({\r\n field: `errors[${index}].code`,\r\n message: 'code must be a string',\r\n path: `/errors/${index}/code`,\r\n code: 'INVALID_TYPE',\r\n value: obj.code,\r\n });\r\n }\r\n\r\n // Validate message (required non-empty string)\r\n if (typeof obj.message !== 'string' || obj.message.length === 0) {\r\n errors.push({\r\n field: `errors[${index}].message`,\r\n message: 'message must be a non-empty string',\r\n path: `/errors/${index}/message`,\r\n code: 'INVALID_TYPE',\r\n value: obj.message,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (obj.stack !== undefined && typeof obj.stack !== 'string') {\r\n errors.push({\r\n field: `errors[${index}].stack`,\r\n message: 'stack must be a string',\r\n path: `/errors/${index}/stack`,\r\n code: 'INVALID_TYPE',\r\n value: obj.stack,\r\n });\r\n }\r\n\r\n if (\r\n obj.context !== undefined &&\r\n (typeof obj.context !== 'object' || obj.context === null)\r\n ) {\r\n errors.push({\r\n field: `errors[${index}].context`,\r\n message: 'context must be an object',\r\n path: `/errors/${index}/context`,\r\n code: 'INVALID_TYPE',\r\n value: obj.context,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate metadata object\r\n */\r\n private validateMetadata(\r\n metadata: Record<string, unknown>,\r\n errors: ValidationError[]\r\n ): void {\r\n // Validate agent_type (required string)\r\n if (typeof metadata.agent_type !== 'string') {\r\n errors.push({\r\n field: 'metadata.agent_type',\r\n message: 'agent_type must be a string',\r\n path: '/metadata/agent_type',\r\n code: 'INVALID_TYPE',\r\n value: metadata.agent_type,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (\r\n metadata.agent_id !== undefined &&\r\n typeof metadata.agent_id !== 'string'\r\n ) {\r\n errors.push({\r\n field: 'metadata.agent_id',\r\n message: 'agent_id must be a string',\r\n path: '/metadata/agent_id',\r\n code: 'INVALID_TYPE',\r\n value: metadata.agent_id,\r\n });\r\n }\r\n\r\n if (\r\n metadata.execution_time_ms !== undefined &&\r\n (typeof metadata.execution_time_ms !== 'number' ||\r\n !Number.isInteger(metadata.execution_time_ms) ||\r\n metadata.execution_time_ms < 0)\r\n ) {\r\n errors.push({\r\n field: 'metadata.execution_time_ms',\r\n message: 'execution_time_ms must be a non-negative integer',\r\n path: '/metadata/execution_time_ms',\r\n code: 'INVALID_TYPE',\r\n value: metadata.execution_time_ms,\r\n });\r\n }\r\n\r\n if (\r\n metadata.timestamp !== undefined &&\r\n typeof metadata.timestamp !== 'string'\r\n ) {\r\n errors.push({\r\n field: 'metadata.timestamp',\r\n message: 'timestamp must be a string (ISO 8601 format)',\r\n path: '/metadata/timestamp',\r\n code: 'INVALID_TYPE',\r\n value: metadata.timestamp,\r\n });\r\n }\r\n\r\n if (\r\n metadata.swarm_id !== undefined &&\r\n typeof metadata.swarm_id !== 'string'\r\n ) {\r\n errors.push({\r\n field: 'metadata.swarm_id',\r\n message: 'swarm_id must be a string',\r\n path: '/metadata/swarm_id',\r\n code: 'INVALID_TYPE',\r\n value: metadata.swarm_id,\r\n });\r\n }\r\n\r\n if (\r\n metadata.iteration !== undefined &&\r\n (typeof metadata.iteration !== 'number' ||\r\n !Number.isInteger(metadata.iteration) ||\r\n metadata.iteration < 1)\r\n ) {\r\n errors.push({\r\n field: 'metadata.iteration',\r\n message: 'iteration must be a positive integer',\r\n path: '/metadata/iteration',\r\n code: 'INVALID_TYPE',\r\n value: metadata.iteration,\r\n });\r\n }\r\n\r\n if (metadata.mode !== undefined) {\r\n const modes: CFNLoopMode[] = ['mvp', 'standard', 'enterprise'];\r\n if (!modes.includes(metadata.mode as CFNLoopMode)) {\r\n errors.push({\r\n field: 'metadata.mode',\r\n message: `mode must be one of: ${modes.join(', ')}`,\r\n path: '/metadata/mode',\r\n code: 'INVALID_ENUM',\r\n value: metadata.mode,\r\n });\r\n }\r\n }\r\n\r\n if (\r\n metadata.context !== undefined &&\r\n (typeof metadata.context !== 'object' || metadata.context === null)\r\n ) {\r\n errors.push({\r\n field: 'metadata.context',\r\n message: 'context must be an object',\r\n path: '/metadata/context',\r\n code: 'INVALID_TYPE',\r\n value: metadata.context,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Format validation errors for display\r\n */\r\n public formatErrors(result: ValidationResult): string {\r\n if (result.valid) {\r\n return 'Agent output is valid.';\r\n }\r\n\r\n let output = `Validation failed with ${result.errors.length} error(s):\\n\\n`;\r\n\r\n for (const error of result.errors) {\r\n output += `[${error.code}] ${error.field}\\n`;\r\n output += ` ${error.message}\\n`;\r\n if (error.value !== undefined) {\r\n // Use sanitizeValue to prevent sensitive data leakage\r\n output += ` Current value: ${sanitizeValue(error.value, error.field)}\\n`;\r\n }\r\n output += '\\n';\r\n }\r\n\r\n if (result.warnings.length > 0) {\r\n output += `\\nWarnings (${result.warnings.length}):\\n`;\r\n for (const warning of result.warnings) {\r\n output += ` - ${warning}\\n`;\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Singleton Instance and Convenience Functions\r\n// ============================================================================\r\n\r\nlet validatorInstance: AgentOutputValidator | null = null;\r\n\r\n/**\r\n * Get or create validator instance\r\n */\r\nexport function getValidator(): AgentOutputValidator {\r\n if (!validatorInstance) {\r\n validatorInstance = new AgentOutputValidator();\r\n }\r\n return validatorInstance;\r\n}\r\n\r\n/**\r\n * Validate agent output object\r\n */\r\nexport function validateAgentOutput(output: unknown): ValidationResult {\r\n return getValidator().validate(output);\r\n}\r\n\r\n/**\r\n * Validate JSON string\r\n */\r\nexport function validateJSON(jsonString: string): ValidationResult {\r\n return getValidator().validateJSON(jsonString);\r\n}\r\n\r\n/**\r\n * Validate Loop 3 output\r\n */\r\nexport function validateLoop3Output(output: unknown): ValidationResult {\r\n const result = getValidator().validate(output);\r\n if (result.valid && result.output_type !== 'loop3') {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'output_type',\r\n message: \"Expected output_type 'loop3'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: result.output_type,\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Validate Loop 2 output\r\n */\r\nexport function validateLoop2Output(output: unknown): ValidationResult {\r\n const result = getValidator().validate(output);\r\n if (result.valid && result.output_type !== 'loop2') {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'output_type',\r\n message: \"Expected output_type 'loop2'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: result.output_type,\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Validate Product Owner output\r\n */\r\nexport function validateProductOwnerOutput(output: unknown): ValidationResult {\r\n const result = getValidator().validate(output);\r\n if (result.valid && result.output_type !== 'product_owner') {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'output_type',\r\n message: \"Expected output_type 'product_owner'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: result.output_type,\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Check if output is valid (boolean shortcut)\r\n */\r\nexport function isValidOutput(output: unknown): boolean {\r\n return getValidator().validate(output).valid;\r\n}\r\n\r\n/**\r\n * Reset validator instance (useful for testing)\r\n */\r\nexport function resetValidator(): void {\r\n validatorInstance = null;\r\n}\r\n\r\nexport default AgentOutputValidator;\r\n"],"names":["sanitizeValue","value","path","sensitivePatterns","lowerPath","toLowerCase","isSensitive","some","pattern","includes","str","JSON","stringify","maxLength","length","substring","AgentOutputValidator","validate","output","errors","warnings","valid","field","message","code","obj","outputType","output_type","push","validateBaseOutput","validateLoop3Output","validateLoop2Output","validateProductOwnerOutput","validateJSON","jsonString","parse","error","Error","String","success","confidence","iteration","Number","isInteger","Array","isArray","i","validateError","metadata","validateMetadata","deliverables","validateDeliverable","metrics","undefined","validateMetrics","summary","validationTypes","validation_type","join","issues","validateIssue","recommendations","approved","decisions","decision","rationale","deliverables_validated","next_action","consensus_score","gate_score","deliverable","index","types","type","statuses","status","size_bytes","lines","checksum","issue","severities","severity","categories","category","location","recommendation","knownMetrics","key","test_coverage","custom_metrics","customMetrics","Object","entries","keys","stack","context","agent_type","agent_id","execution_time_ms","timestamp","swarm_id","mode","modes","formatErrors","result","warning","validatorInstance","getValidator","validateAgentOutput","isValidOutput","resetValidator"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/agent-output-validator.ts"],"sourcesContent":["/**\r\n * Agent Output Validator\r\n * Zero-dependency validation library for CFN agent outputs\r\n *\r\n * @version 1.0.0\r\n * @description Type-safe validation with detailed error reporting\r\n */\r\n\r\nimport type {\r\n AgentOutput,\r\n Loop3Output,\r\n Loop2Output,\r\n ProductOwnerOutput,\r\n ValidationResult,\r\n ValidationError,\r\n Deliverable,\r\n Issue,\r\n Metrics,\r\n AgentError,\r\n AgentMetadata,\r\n DeliverableType,\r\n DeliverableStatus,\r\n IssueSeverity,\r\n IssueCategory,\r\n ValidationType,\r\n ProductOwnerDecision,\r\n CFNLoopMode,\r\n} from '../types/agent-output.js';\r\n\r\n// ============================================================================\r\n// Security Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Sanitize values for safe logging (prevents sensitive data leakage)\r\n * @param value - Value to sanitize\r\n * @param path - Field path for sensitive field detection\r\n * @returns Sanitized string representation\r\n */\r\nfunction sanitizeValue(value: unknown, path: string): string {\r\n // List of sensitive field patterns\r\n const sensitivePatterns = [\r\n 'password',\r\n 'passwd',\r\n 'pwd',\r\n 'token',\r\n 'key',\r\n 'secret',\r\n 'api_key',\r\n 'apikey',\r\n 'api-key',\r\n 'auth',\r\n 'credential',\r\n 'private',\r\n ];\r\n\r\n // Check if path contains sensitive field name\r\n const lowerPath = path.toLowerCase();\r\n const isSensitive = sensitivePatterns.some((pattern) =>\r\n lowerPath.includes(pattern)\r\n );\r\n\r\n if (isSensitive) {\r\n return '[REDACTED]';\r\n }\r\n\r\n // Sanitize value for safe display\r\n try {\r\n const str = JSON.stringify(value);\r\n\r\n // Truncate large values to prevent log flooding\r\n const maxLength = 100;\r\n if (str.length > maxLength) {\r\n return str.substring(0, maxLength) + '...[truncated]';\r\n }\r\n\r\n return str;\r\n } catch {\r\n // Handle circular references or non-serializable values\r\n return '[Non-serializable value]';\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Validation Class\r\n// ============================================================================\r\n\r\n/**\r\n * AgentOutputValidator: Main validation class\r\n * Provides schema validation, error reporting, and type checking\r\n */\r\nexport class AgentOutputValidator {\r\n /**\r\n * Validate agent output object\r\n */\r\n public validate(output: unknown): ValidationResult {\r\n const errors: ValidationError[] = [];\r\n const warnings: string[] = [];\r\n\r\n if (typeof output !== 'object' || output === null) {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'root',\r\n message: 'Agent output must be a valid JSON object',\r\n path: '/',\r\n code: 'INVALID_TYPE',\r\n },\r\n ],\r\n warnings,\r\n };\r\n }\r\n\r\n const obj = output as Record<string, unknown>;\r\n\r\n // Validate output_type discriminator\r\n const outputType = obj.output_type;\r\n if (\r\n outputType !== 'loop3' &&\r\n outputType !== 'loop2' &&\r\n outputType !== 'product_owner'\r\n ) {\r\n errors.push({\r\n field: 'output_type',\r\n message:\r\n \"output_type must be one of: 'loop3', 'loop2', 'product_owner'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: outputType,\r\n });\r\n return { valid: false, errors, warnings };\r\n }\r\n\r\n // Validate base fields common to all outputs\r\n this.validateBaseOutput(obj, errors);\r\n\r\n // Validate type-specific fields\r\n switch (outputType) {\r\n case 'loop3':\r\n this.validateLoop3Output(obj, errors, warnings);\r\n break;\r\n case 'loop2':\r\n this.validateLoop2Output(obj, errors, warnings);\r\n break;\r\n case 'product_owner':\r\n this.validateProductOwnerOutput(obj, errors, warnings);\r\n break;\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n warnings,\r\n output_type: outputType,\r\n };\r\n }\r\n\r\n /**\r\n * Validate JSON string\r\n */\r\n public validateJSON(jsonString: string): ValidationResult {\r\n try {\r\n const output = JSON.parse(jsonString);\r\n return this.validate(output);\r\n } catch (error) {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'json',\r\n message: `Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}`,\r\n path: 'root',\r\n code: 'JSON_PARSE_ERROR',\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Validate base output fields (common to all types)\r\n */\r\n private validateBaseOutput(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[]\r\n ): void {\r\n // Validate success (required boolean)\r\n if (typeof obj.success !== 'boolean') {\r\n errors.push({\r\n field: 'success',\r\n message: 'success must be a boolean',\r\n path: '/success',\r\n code: 'INVALID_TYPE',\r\n value: obj.success,\r\n });\r\n }\r\n\r\n // Validate confidence (required number 0.0-1.0)\r\n if (typeof obj.confidence !== 'number') {\r\n errors.push({\r\n field: 'confidence',\r\n message: 'confidence must be a number',\r\n path: '/confidence',\r\n code: 'INVALID_TYPE',\r\n value: obj.confidence,\r\n });\r\n } else if (obj.confidence < 0.0 || obj.confidence > 1.0) {\r\n errors.push({\r\n field: 'confidence',\r\n message: 'confidence must be between 0.0 and 1.0',\r\n path: '/confidence',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.confidence,\r\n });\r\n }\r\n\r\n // Validate iteration (required positive integer)\r\n if (typeof obj.iteration !== 'number') {\r\n errors.push({\r\n field: 'iteration',\r\n message: 'iteration must be a number',\r\n path: '/iteration',\r\n code: 'INVALID_TYPE',\r\n value: obj.iteration,\r\n });\r\n } else if (!Number.isInteger(obj.iteration) || obj.iteration < 1) {\r\n errors.push({\r\n field: 'iteration',\r\n message: 'iteration must be a positive integer',\r\n path: '/iteration',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.iteration,\r\n });\r\n }\r\n\r\n // Validate errors (required array)\r\n if (!Array.isArray(obj.errors)) {\r\n errors.push({\r\n field: 'errors',\r\n message: 'errors must be an array',\r\n path: '/errors',\r\n code: 'INVALID_TYPE',\r\n value: obj.errors,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.errors.length; i++) {\r\n this.validateError(obj.errors[i], i, errors);\r\n }\r\n }\r\n\r\n // Validate metadata (required object)\r\n if (typeof obj.metadata !== 'object' || obj.metadata === null) {\r\n errors.push({\r\n field: 'metadata',\r\n message: 'metadata must be an object',\r\n path: '/metadata',\r\n code: 'INVALID_TYPE',\r\n value: obj.metadata,\r\n });\r\n } else {\r\n this.validateMetadata(\r\n obj.metadata as Record<string, unknown>,\r\n errors\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Validate Loop 3 (Implementer) output\r\n */\r\n private validateLoop3Output(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[],\r\n warnings: string[]\r\n ): void {\r\n // Validate deliverables (required array)\r\n if (!Array.isArray(obj.deliverables)) {\r\n errors.push({\r\n field: 'deliverables',\r\n message: 'deliverables must be an array',\r\n path: '/deliverables',\r\n code: 'INVALID_TYPE',\r\n value: obj.deliverables,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.deliverables.length; i++) {\r\n this.validateDeliverable(obj.deliverables[i], i, errors);\r\n }\r\n\r\n if (obj.deliverables.length === 0) {\r\n warnings.push('Loop 3 output has no deliverables (empty array)');\r\n }\r\n }\r\n\r\n // Validate metrics (optional object)\r\n if (obj.metrics !== undefined) {\r\n if (typeof obj.metrics !== 'object' || obj.metrics === null) {\r\n errors.push({\r\n field: 'metrics',\r\n message: 'metrics must be an object',\r\n path: '/metrics',\r\n code: 'INVALID_TYPE',\r\n value: obj.metrics,\r\n });\r\n } else {\r\n this.validateMetrics(obj.metrics as Record<string, unknown>, errors);\r\n }\r\n }\r\n\r\n // Validate summary (optional string)\r\n if (obj.summary !== undefined && typeof obj.summary !== 'string') {\r\n errors.push({\r\n field: 'summary',\r\n message: 'summary must be a string',\r\n path: '/summary',\r\n code: 'INVALID_TYPE',\r\n value: obj.summary,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate Loop 2 (Validator) output\r\n */\r\n private validateLoop2Output(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[],\r\n warnings: string[]\r\n ): void {\r\n // Validate validation_type (required enum)\r\n const validationTypes: ValidationType[] = [\r\n 'review',\r\n 'test',\r\n 'security',\r\n 'architecture',\r\n 'performance',\r\n 'compliance',\r\n ];\r\n if (!validationTypes.includes(obj.validation_type as ValidationType)) {\r\n errors.push({\r\n field: 'validation_type',\r\n message: `validation_type must be one of: ${validationTypes.join(', ')}`,\r\n path: '/validation_type',\r\n code: 'INVALID_ENUM',\r\n value: obj.validation_type,\r\n });\r\n }\r\n\r\n // Validate issues (optional array, default to empty)\r\n if (obj.issues !== undefined) {\r\n if (!Array.isArray(obj.issues)) {\r\n errors.push({\r\n field: 'issues',\r\n message: 'issues must be an array',\r\n path: '/issues',\r\n code: 'INVALID_TYPE',\r\n value: obj.issues,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.issues.length; i++) {\r\n this.validateIssue(obj.issues[i], i, errors);\r\n }\r\n }\r\n }\r\n\r\n // Validate recommendations (optional array, default to empty)\r\n if (obj.recommendations !== undefined) {\r\n if (!Array.isArray(obj.recommendations)) {\r\n errors.push({\r\n field: 'recommendations',\r\n message: 'recommendations must be an array',\r\n path: '/recommendations',\r\n code: 'INVALID_TYPE',\r\n value: obj.recommendations,\r\n });\r\n } else {\r\n for (let i = 0; i < obj.recommendations.length; i++) {\r\n if (typeof obj.recommendations[i] !== 'string') {\r\n errors.push({\r\n field: `recommendations[${i}]`,\r\n message: 'recommendation must be a string',\r\n path: `/recommendations/${i}`,\r\n code: 'INVALID_TYPE',\r\n value: obj.recommendations[i],\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Validate approved (required boolean)\r\n if (typeof obj.approved !== 'boolean') {\r\n errors.push({\r\n field: 'approved',\r\n message: 'approved must be a boolean',\r\n path: '/approved',\r\n code: 'INVALID_TYPE',\r\n value: obj.approved,\r\n });\r\n }\r\n\r\n // Validate summary (optional string)\r\n if (obj.summary !== undefined && typeof obj.summary !== 'string') {\r\n errors.push({\r\n field: 'summary',\r\n message: 'summary must be a string',\r\n path: '/summary',\r\n code: 'INVALID_TYPE',\r\n value: obj.summary,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate Product Owner output\r\n */\r\n private validateProductOwnerOutput(\r\n obj: Record<string, unknown>,\r\n errors: ValidationError[],\r\n warnings: string[]\r\n ): void {\r\n // Validate decision (required enum)\r\n const decisions: ProductOwnerDecision[] = [\r\n 'PROCEED',\r\n 'ITERATE',\r\n 'ABORT',\r\n ];\r\n if (!decisions.includes(obj.decision as ProductOwnerDecision)) {\r\n errors.push({\r\n field: 'decision',\r\n message: `decision must be one of: ${decisions.join(', ')}`,\r\n path: '/decision',\r\n code: 'INVALID_ENUM',\r\n value: obj.decision,\r\n });\r\n }\r\n\r\n // Validate rationale (required non-empty string)\r\n if (typeof obj.rationale !== 'string') {\r\n errors.push({\r\n field: 'rationale',\r\n message: 'rationale must be a string',\r\n path: '/rationale',\r\n code: 'INVALID_TYPE',\r\n value: obj.rationale,\r\n });\r\n } else if ((obj.rationale as string).length === 0) {\r\n errors.push({\r\n field: 'rationale',\r\n message: 'rationale must be a non-empty string',\r\n path: '/rationale',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.rationale,\r\n });\r\n }\r\n\r\n // Validate deliverables_validated (required boolean)\r\n if (typeof obj.deliverables_validated !== 'boolean') {\r\n errors.push({\r\n field: 'deliverables_validated',\r\n message: 'deliverables_validated must be a boolean',\r\n path: '/deliverables_validated',\r\n code: 'INVALID_TYPE',\r\n value: obj.deliverables_validated,\r\n });\r\n }\r\n\r\n // Validate next_action (required string)\r\n if (typeof obj.next_action !== 'string') {\r\n errors.push({\r\n field: 'next_action',\r\n message: 'next_action must be a string',\r\n path: '/next_action',\r\n code: 'INVALID_TYPE',\r\n value: obj.next_action,\r\n });\r\n }\r\n\r\n // Validate consensus_score (optional number 0.0-1.0)\r\n if (obj.consensus_score !== undefined) {\r\n if (typeof obj.consensus_score !== 'number') {\r\n errors.push({\r\n field: 'consensus_score',\r\n message: 'consensus_score must be a number',\r\n path: '/consensus_score',\r\n code: 'INVALID_TYPE',\r\n value: obj.consensus_score,\r\n });\r\n } else if (\r\n obj.consensus_score < 0.0 ||\r\n obj.consensus_score > 1.0\r\n ) {\r\n errors.push({\r\n field: 'consensus_score',\r\n message: 'consensus_score must be between 0.0 and 1.0',\r\n path: '/consensus_score',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.consensus_score,\r\n });\r\n }\r\n }\r\n\r\n // Validate gate_score (optional number 0.0-1.0)\r\n if (obj.gate_score !== undefined) {\r\n if (typeof obj.gate_score !== 'number') {\r\n errors.push({\r\n field: 'gate_score',\r\n message: 'gate_score must be a number',\r\n path: '/gate_score',\r\n code: 'INVALID_TYPE',\r\n value: obj.gate_score,\r\n });\r\n } else if (obj.gate_score < 0.0 || obj.gate_score > 1.0) {\r\n errors.push({\r\n field: 'gate_score',\r\n message: 'gate_score must be between 0.0 and 1.0',\r\n path: '/gate_score',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: obj.gate_score,\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validate deliverable object\r\n */\r\n private validateDeliverable(\r\n deliverable: unknown,\r\n index: number,\r\n errors: ValidationError[]\r\n ): void {\r\n if (typeof deliverable !== 'object' || deliverable === null) {\r\n errors.push({\r\n field: `deliverables[${index}]`,\r\n message: 'deliverable must be an object',\r\n path: `/deliverables/${index}`,\r\n code: 'INVALID_TYPE',\r\n value: deliverable,\r\n });\r\n return;\r\n }\r\n\r\n const obj = deliverable as Record<string, unknown>;\r\n\r\n // Validate path (required non-empty string)\r\n if (typeof obj.path !== 'string' || obj.path.length === 0) {\r\n errors.push({\r\n field: `deliverables[${index}].path`,\r\n message: 'path must be a non-empty string',\r\n path: `/deliverables/${index}/path`,\r\n code: 'INVALID_TYPE',\r\n value: obj.path,\r\n });\r\n }\r\n\r\n // Validate type (required enum)\r\n const types: DeliverableType[] = [\r\n 'implementation',\r\n 'test',\r\n 'documentation',\r\n 'config',\r\n 'schema',\r\n 'script',\r\n 'other',\r\n ];\r\n if (!types.includes(obj.type as DeliverableType)) {\r\n errors.push({\r\n field: `deliverables[${index}].type`,\r\n message: `type must be one of: ${types.join(', ')}`,\r\n path: `/deliverables/${index}/type`,\r\n code: 'INVALID_ENUM',\r\n value: obj.type,\r\n });\r\n }\r\n\r\n // Validate status (required enum)\r\n const statuses: DeliverableStatus[] = [\r\n 'created',\r\n 'modified',\r\n 'deleted',\r\n 'validated',\r\n 'pending',\r\n ];\r\n if (!statuses.includes(obj.status as DeliverableStatus)) {\r\n errors.push({\r\n field: `deliverables[${index}].status`,\r\n message: `status must be one of: ${statuses.join(', ')}`,\r\n path: `/deliverables/${index}/status`,\r\n code: 'INVALID_ENUM',\r\n value: obj.status,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (\r\n obj.size_bytes !== undefined &&\r\n (typeof obj.size_bytes !== 'number' ||\r\n !Number.isInteger(obj.size_bytes) ||\r\n obj.size_bytes < 0)\r\n ) {\r\n errors.push({\r\n field: `deliverables[${index}].size_bytes`,\r\n message: 'size_bytes must be a non-negative integer',\r\n path: `/deliverables/${index}/size_bytes`,\r\n code: 'INVALID_TYPE',\r\n value: obj.size_bytes,\r\n });\r\n }\r\n\r\n if (\r\n obj.lines !== undefined &&\r\n (typeof obj.lines !== 'number' ||\r\n !Number.isInteger(obj.lines) ||\r\n obj.lines < 0)\r\n ) {\r\n errors.push({\r\n field: `deliverables[${index}].lines`,\r\n message: 'lines must be a non-negative integer',\r\n path: `/deliverables/${index}/lines`,\r\n code: 'INVALID_TYPE',\r\n value: obj.lines,\r\n });\r\n }\r\n\r\n if (obj.checksum !== undefined && typeof obj.checksum !== 'string') {\r\n errors.push({\r\n field: `deliverables[${index}].checksum`,\r\n message: 'checksum must be a string',\r\n path: `/deliverables/${index}/checksum`,\r\n code: 'INVALID_TYPE',\r\n value: obj.checksum,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate issue object\r\n */\r\n private validateIssue(\r\n issue: unknown,\r\n index: number,\r\n errors: ValidationError[]\r\n ): void {\r\n if (typeof issue !== 'object' || issue === null) {\r\n errors.push({\r\n field: `issues[${index}]`,\r\n message: 'issue must be an object',\r\n path: `/issues/${index}`,\r\n code: 'INVALID_TYPE',\r\n value: issue,\r\n });\r\n return;\r\n }\r\n\r\n const obj = issue as Record<string, unknown>;\r\n\r\n // Validate severity (required enum)\r\n const severities: IssueSeverity[] = [\r\n 'critical',\r\n 'high',\r\n 'medium',\r\n 'low',\r\n 'info',\r\n ];\r\n if (!severities.includes(obj.severity as IssueSeverity)) {\r\n errors.push({\r\n field: `issues[${index}].severity`,\r\n message: `severity must be one of: ${severities.join(', ')}`,\r\n path: `/issues/${index}/severity`,\r\n code: 'INVALID_ENUM',\r\n value: obj.severity,\r\n });\r\n }\r\n\r\n // Validate category (required enum)\r\n const categories: IssueCategory[] = [\r\n 'security',\r\n 'performance',\r\n 'quality',\r\n 'style',\r\n 'documentation',\r\n 'testing',\r\n 'architecture',\r\n 'other',\r\n ];\r\n if (!categories.includes(obj.category as IssueCategory)) {\r\n errors.push({\r\n field: `issues[${index}].category`,\r\n message: `category must be one of: ${categories.join(', ')}`,\r\n path: `/issues/${index}/category`,\r\n code: 'INVALID_ENUM',\r\n value: obj.category,\r\n });\r\n }\r\n\r\n // Validate message (required non-empty string)\r\n if (typeof obj.message !== 'string' || obj.message.length === 0) {\r\n errors.push({\r\n field: `issues[${index}].message`,\r\n message: 'message must be a non-empty string',\r\n path: `/issues/${index}/message`,\r\n code: 'INVALID_TYPE',\r\n value: obj.message,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (obj.location !== undefined && typeof obj.location !== 'string') {\r\n errors.push({\r\n field: `issues[${index}].location`,\r\n message: 'location must be a string',\r\n path: `/issues/${index}/location`,\r\n code: 'INVALID_TYPE',\r\n value: obj.location,\r\n });\r\n }\r\n\r\n if (\r\n obj.recommendation !== undefined &&\r\n typeof obj.recommendation !== 'string'\r\n ) {\r\n errors.push({\r\n field: `issues[${index}].recommendation`,\r\n message: 'recommendation must be a string',\r\n path: `/issues/${index}/recommendation`,\r\n code: 'INVALID_TYPE',\r\n value: obj.recommendation,\r\n });\r\n }\r\n\r\n if (obj.code !== undefined && typeof obj.code !== 'string') {\r\n errors.push({\r\n field: `issues[${index}].code`,\r\n message: 'code must be a string',\r\n path: `/issues/${index}/code`,\r\n code: 'INVALID_TYPE',\r\n value: obj.code,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate metrics object\r\n */\r\n private validateMetrics(\r\n metrics: Record<string, unknown>,\r\n errors: ValidationError[]\r\n ): void {\r\n // All metrics fields are optional numbers\r\n const knownMetrics = [\r\n 'files_created',\r\n 'files_modified',\r\n 'files_deleted',\r\n 'lines_of_code',\r\n 'test_coverage',\r\n 'tests_passed',\r\n 'tests_failed',\r\n 'execution_time_ms',\r\n 'memory_usage_mb',\r\n ];\r\n\r\n for (const key of knownMetrics) {\r\n if (metrics[key] !== undefined && typeof metrics[key] !== 'number') {\r\n errors.push({\r\n field: `metrics.${key}`,\r\n message: `${key} must be a number`,\r\n path: `/metrics/${key}`,\r\n code: 'INVALID_TYPE',\r\n value: metrics[key],\r\n });\r\n }\r\n }\r\n\r\n // Validate test_coverage range\r\n if (\r\n metrics.test_coverage !== undefined &&\r\n typeof metrics.test_coverage === 'number' &&\r\n (metrics.test_coverage < 0.0 || metrics.test_coverage > 1.0)\r\n ) {\r\n errors.push({\r\n field: 'metrics.test_coverage',\r\n message: 'test_coverage must be between 0.0 and 1.0',\r\n path: '/metrics/test_coverage',\r\n code: 'CONSTRAINT_VIOLATION',\r\n value: metrics.test_coverage,\r\n });\r\n }\r\n\r\n // Validate custom_metrics (if present)\r\n if (metrics.custom_metrics !== undefined) {\r\n if (\r\n typeof metrics.custom_metrics !== 'object' ||\r\n metrics.custom_metrics === null\r\n ) {\r\n errors.push({\r\n field: 'metrics.custom_metrics',\r\n message: 'custom_metrics must be an object',\r\n path: '/metrics/custom_metrics',\r\n code: 'INVALID_TYPE',\r\n value: metrics.custom_metrics,\r\n });\r\n } else {\r\n const customMetrics = metrics.custom_metrics as Record<string, unknown>;\r\n for (const [key, value] of Object.entries(customMetrics)) {\r\n if (typeof value !== 'number') {\r\n errors.push({\r\n field: `metrics.custom_metrics.${key}`,\r\n message: `custom_metrics.${key} must be a number`,\r\n path: `/metrics/custom_metrics/${key}`,\r\n code: 'INVALID_TYPE',\r\n value,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Check for unknown fields (not in known metrics or custom_metrics)\r\n for (const key of Object.keys(metrics)) {\r\n if (key !== 'custom_metrics' && !knownMetrics.includes(key)) {\r\n errors.push({\r\n field: `metrics.${key}`,\r\n message: `Unknown metric field '${key}'. Use 'custom_metrics' for extensibility.`,\r\n path: `/metrics/${key}`,\r\n code: 'UNKNOWN_FIELD',\r\n value: metrics[key],\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validate error object\r\n */\r\n private validateError(\r\n error: unknown,\r\n index: number,\r\n errors: ValidationError[]\r\n ): void {\r\n if (typeof error !== 'object' || error === null) {\r\n errors.push({\r\n field: `errors[${index}]`,\r\n message: 'error must be an object',\r\n path: `/errors/${index}`,\r\n code: 'INVALID_TYPE',\r\n value: error,\r\n });\r\n return;\r\n }\r\n\r\n const obj = error as Record<string, unknown>;\r\n\r\n // Validate code (required string)\r\n if (typeof obj.code !== 'string') {\r\n errors.push({\r\n field: `errors[${index}].code`,\r\n message: 'code must be a string',\r\n path: `/errors/${index}/code`,\r\n code: 'INVALID_TYPE',\r\n value: obj.code,\r\n });\r\n }\r\n\r\n // Validate message (required non-empty string)\r\n if (typeof obj.message !== 'string' || obj.message.length === 0) {\r\n errors.push({\r\n field: `errors[${index}].message`,\r\n message: 'message must be a non-empty string',\r\n path: `/errors/${index}/message`,\r\n code: 'INVALID_TYPE',\r\n value: obj.message,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (obj.stack !== undefined && typeof obj.stack !== 'string') {\r\n errors.push({\r\n field: `errors[${index}].stack`,\r\n message: 'stack must be a string',\r\n path: `/errors/${index}/stack`,\r\n code: 'INVALID_TYPE',\r\n value: obj.stack,\r\n });\r\n }\r\n\r\n if (\r\n obj.context !== undefined &&\r\n (typeof obj.context !== 'object' || obj.context === null)\r\n ) {\r\n errors.push({\r\n field: `errors[${index}].context`,\r\n message: 'context must be an object',\r\n path: `/errors/${index}/context`,\r\n code: 'INVALID_TYPE',\r\n value: obj.context,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Validate metadata object\r\n */\r\n private validateMetadata(\r\n metadata: Record<string, unknown>,\r\n errors: ValidationError[]\r\n ): void {\r\n // Validate agent_type (required string)\r\n if (typeof metadata.agent_type !== 'string') {\r\n errors.push({\r\n field: 'metadata.agent_type',\r\n message: 'agent_type must be a string',\r\n path: '/metadata/agent_type',\r\n code: 'INVALID_TYPE',\r\n value: metadata.agent_type,\r\n });\r\n }\r\n\r\n // Validate optional fields\r\n if (\r\n metadata.agent_id !== undefined &&\r\n typeof metadata.agent_id !== 'string'\r\n ) {\r\n errors.push({\r\n field: 'metadata.agent_id',\r\n message: 'agent_id must be a string',\r\n path: '/metadata/agent_id',\r\n code: 'INVALID_TYPE',\r\n value: metadata.agent_id,\r\n });\r\n }\r\n\r\n if (\r\n metadata.execution_time_ms !== undefined &&\r\n (typeof metadata.execution_time_ms !== 'number' ||\r\n !Number.isInteger(metadata.execution_time_ms) ||\r\n metadata.execution_time_ms < 0)\r\n ) {\r\n errors.push({\r\n field: 'metadata.execution_time_ms',\r\n message: 'execution_time_ms must be a non-negative integer',\r\n path: '/metadata/execution_time_ms',\r\n code: 'INVALID_TYPE',\r\n value: metadata.execution_time_ms,\r\n });\r\n }\r\n\r\n if (\r\n metadata.timestamp !== undefined &&\r\n typeof metadata.timestamp !== 'string'\r\n ) {\r\n errors.push({\r\n field: 'metadata.timestamp',\r\n message: 'timestamp must be a string (ISO 8601 format)',\r\n path: '/metadata/timestamp',\r\n code: 'INVALID_TYPE',\r\n value: metadata.timestamp,\r\n });\r\n }\r\n\r\n if (\r\n metadata.swarm_id !== undefined &&\r\n typeof metadata.swarm_id !== 'string'\r\n ) {\r\n errors.push({\r\n field: 'metadata.swarm_id',\r\n message: 'swarm_id must be a string',\r\n path: '/metadata/swarm_id',\r\n code: 'INVALID_TYPE',\r\n value: metadata.swarm_id,\r\n });\r\n }\r\n\r\n if (\r\n metadata.iteration !== undefined &&\r\n (typeof metadata.iteration !== 'number' ||\r\n !Number.isInteger(metadata.iteration) ||\r\n metadata.iteration < 1)\r\n ) {\r\n errors.push({\r\n field: 'metadata.iteration',\r\n message: 'iteration must be a positive integer',\r\n path: '/metadata/iteration',\r\n code: 'INVALID_TYPE',\r\n value: metadata.iteration,\r\n });\r\n }\r\n\r\n if (metadata.mode !== undefined) {\r\n const modes: CFNLoopMode[] = ['mvp', 'standard', 'enterprise'];\r\n if (!modes.includes(metadata.mode as CFNLoopMode)) {\r\n errors.push({\r\n field: 'metadata.mode',\r\n message: `mode must be one of: ${modes.join(', ')}`,\r\n path: '/metadata/mode',\r\n code: 'INVALID_ENUM',\r\n value: metadata.mode,\r\n });\r\n }\r\n }\r\n\r\n if (\r\n metadata.context !== undefined &&\r\n (typeof metadata.context !== 'object' || metadata.context === null)\r\n ) {\r\n errors.push({\r\n field: 'metadata.context',\r\n message: 'context must be an object',\r\n path: '/metadata/context',\r\n code: 'INVALID_TYPE',\r\n value: metadata.context,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Format validation errors for display\r\n */\r\n public formatErrors(result: ValidationResult): string {\r\n if (result.valid) {\r\n return 'Agent output is valid.';\r\n }\r\n\r\n let output = `Validation failed with ${result.errors.length} error(s):\\n\\n`;\r\n\r\n for (const error of result.errors) {\r\n output += `[${error.code}] ${error.field}\\n`;\r\n output += ` ${error.message}\\n`;\r\n if (error.value !== undefined) {\r\n // Use sanitizeValue to prevent sensitive data leakage\r\n output += ` Current value: ${sanitizeValue(error.value, error.field)}\\n`;\r\n }\r\n output += '\\n';\r\n }\r\n\r\n if (result.warnings.length > 0) {\r\n output += `\\nWarnings (${result.warnings.length}):\\n`;\r\n for (const warning of result.warnings) {\r\n output += ` - ${warning}\\n`;\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Singleton Instance and Convenience Functions\r\n// ============================================================================\r\n\r\nlet validatorInstance: AgentOutputValidator | null = null;\r\n\r\n/**\r\n * Get or create validator instance\r\n */\r\nexport function getValidator(): AgentOutputValidator {\r\n if (!validatorInstance) {\r\n validatorInstance = new AgentOutputValidator();\r\n }\r\n return validatorInstance;\r\n}\r\n\r\n/**\r\n * Validate agent output object\r\n */\r\nexport function validateAgentOutput(output: unknown): ValidationResult {\r\n return getValidator().validate(output);\r\n}\r\n\r\n/**\r\n * Validate JSON string\r\n */\r\nexport function validateJSON(jsonString: string): ValidationResult {\r\n return getValidator().validateJSON(jsonString);\r\n}\r\n\r\n/**\r\n * Validate Loop 3 output\r\n */\r\nexport function validateLoop3Output(output: unknown): ValidationResult {\r\n const result = getValidator().validate(output);\r\n if (result.valid && result.output_type !== 'loop3') {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'output_type',\r\n message: \"Expected output_type 'loop3'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: result.output_type,\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Validate Loop 2 output\r\n */\r\nexport function validateLoop2Output(output: unknown): ValidationResult {\r\n const result = getValidator().validate(output);\r\n if (result.valid && result.output_type !== 'loop2') {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'output_type',\r\n message: \"Expected output_type 'loop2'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: result.output_type,\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Validate Product Owner output\r\n */\r\nexport function validateProductOwnerOutput(output: unknown): ValidationResult {\r\n const result = getValidator().validate(output);\r\n if (result.valid && result.output_type !== 'product_owner') {\r\n return {\r\n valid: false,\r\n errors: [\r\n {\r\n field: 'output_type',\r\n message: \"Expected output_type 'product_owner'\",\r\n path: '/output_type',\r\n code: 'INVALID_OUTPUT_TYPE',\r\n value: result.output_type,\r\n },\r\n ],\r\n warnings: [],\r\n };\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Check if output is valid (boolean shortcut)\r\n */\r\nexport function isValidOutput(output: unknown): boolean {\r\n return getValidator().validate(output).valid;\r\n}\r\n\r\n/**\r\n * Reset validator instance (useful for testing)\r\n */\r\nexport function resetValidator(): void {\r\n validatorInstance = null;\r\n}\r\n\r\nexport default AgentOutputValidator;\r\n"],"names":["sanitizeValue","value","path","sensitivePatterns","lowerPath","toLowerCase","isSensitive","some","pattern","includes","str","JSON","stringify","maxLength","length","substring","AgentOutputValidator","validate","output","errors","warnings","valid","field","message","code","obj","outputType","output_type","push","validateBaseOutput","validateLoop3Output","validateLoop2Output","validateProductOwnerOutput","validateJSON","jsonString","parse","error","Error","String","success","confidence","iteration","Number","isInteger","Array","isArray","i","validateError","metadata","validateMetadata","deliverables","validateDeliverable","metrics","undefined","validateMetrics","summary","validationTypes","validation_type","join","issues","validateIssue","recommendations","approved","decisions","decision","rationale","deliverables_validated","next_action","consensus_score","gate_score","deliverable","index","types","type","statuses","status","size_bytes","lines","checksum","issue","severities","severity","categories","category","location","recommendation","knownMetrics","key","test_coverage","custom_metrics","customMetrics","Object","entries","keys","stack","context","agent_type","agent_id","execution_time_ms","timestamp","swarm_id","mode","modes","formatErrors","result","warning","validatorInstance","getValidator","validateAgentOutput","isValidOutput","resetValidator"],"mappings":"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"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Workspace Management
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent, organized workspace for agent outputs with reliable completion signals.
|
|
5
|
+
* Part of Task 2.1: Persistent Agent Output Workspace (Integration)
|
|
6
|
+
*
|
|
7
|
+
* Directory Structure:
|
|
8
|
+
* artifacts/agent-workspaces/{task_id}/{agent_id}/
|
|
9
|
+
* ├── logs/ (stdout.log, stderr.log)
|
|
10
|
+
* ├── reports/ (analysis.json, etc.)
|
|
11
|
+
* ├── metrics/ (performance.json, etc.)
|
|
12
|
+
* ├── deliverables/ (output files)
|
|
13
|
+
* └── COMPLETION_SIGNAL.json
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* const workspace = await createWorkspace('task-123', 'agent-456');
|
|
17
|
+
* await writeOutput(workspace, 'logs', 'stdout.log', 'Log content');
|
|
18
|
+
* await signalCompletion(workspace, { success: true, confidence: 0.85 });
|
|
19
|
+
*/ import * as path from 'path';
|
|
20
|
+
import { atomicWrite, ensureDirectory } from './file-operations.js';
|
|
21
|
+
import { createLogger } from './logging.js';
|
|
22
|
+
import { createError, ErrorCode } from './errors.js';
|
|
23
|
+
import { writeCompletionSignal } from './completion-signal-handler.js';
|
|
24
|
+
const logger = createLogger('agent-workspace');
|
|
25
|
+
/**
|
|
26
|
+
* Workspace configuration
|
|
27
|
+
*/ const WORKSPACE_ROOT = path.resolve(process.cwd(), 'artifacts', 'agent-workspaces');
|
|
28
|
+
/**
|
|
29
|
+
* Create a workspace for an agent
|
|
30
|
+
*
|
|
31
|
+
* Pattern: Atomic directory creation with race-condition safety
|
|
32
|
+
*
|
|
33
|
+
* @param taskId - Unique task identifier
|
|
34
|
+
* @param agentId - Unique agent identifier
|
|
35
|
+
* @param options - Workspace creation options
|
|
36
|
+
* @returns Workspace path information
|
|
37
|
+
* @throws INVALID_INPUT if taskId or agentId is invalid
|
|
38
|
+
* @throws DIRECTORY_CREATE_FAILED if directory creation fails
|
|
39
|
+
*/ export async function createWorkspace(taskId, agentId, options = {}) {
|
|
40
|
+
// Validate inputs
|
|
41
|
+
if (!taskId || typeof taskId !== 'string') {
|
|
42
|
+
throw createError(ErrorCode.INVALID_INPUT, 'Task ID must be a non-empty string', {
|
|
43
|
+
taskId
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (!agentId || typeof agentId !== 'string') {
|
|
47
|
+
throw createError(ErrorCode.INVALID_INPUT, 'Agent ID must be a non-empty string', {
|
|
48
|
+
agentId
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Sanitize IDs to prevent path traversal
|
|
52
|
+
const sanitizedTaskId = sanitizeId(taskId);
|
|
53
|
+
const sanitizedAgentId = sanitizeId(agentId);
|
|
54
|
+
const workspaceRoot = options.workspaceRoot || WORKSPACE_ROOT;
|
|
55
|
+
const workspacePath = path.join(workspaceRoot, sanitizedTaskId, sanitizedAgentId);
|
|
56
|
+
// Define subdirectories
|
|
57
|
+
const subdirectories = {
|
|
58
|
+
logs: path.join(workspacePath, 'logs'),
|
|
59
|
+
reports: path.join(workspacePath, 'reports'),
|
|
60
|
+
metrics: path.join(workspacePath, 'metrics'),
|
|
61
|
+
deliverables: path.join(workspacePath, 'deliverables')
|
|
62
|
+
};
|
|
63
|
+
// Create directories (atomic, race-condition safe)
|
|
64
|
+
if (!options.skipCreate) {
|
|
65
|
+
try {
|
|
66
|
+
await ensureDirectory(workspacePath);
|
|
67
|
+
await Promise.all(Object.values(subdirectories).map((dir)=>ensureDirectory(dir)));
|
|
68
|
+
logger.info('Workspace created', {
|
|
69
|
+
taskId,
|
|
70
|
+
agentId,
|
|
71
|
+
workspacePath
|
|
72
|
+
});
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throw createError(ErrorCode.DIRECTORY_CREATE_FAILED, 'Failed to create workspace directories', {
|
|
75
|
+
taskId,
|
|
76
|
+
agentId,
|
|
77
|
+
workspacePath,
|
|
78
|
+
error: error.message
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
path: workspacePath,
|
|
84
|
+
taskId: sanitizedTaskId,
|
|
85
|
+
agentId: sanitizedAgentId,
|
|
86
|
+
subdirectories
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get the path to an existing workspace
|
|
91
|
+
*
|
|
92
|
+
* @param taskId - Unique task identifier
|
|
93
|
+
* @param agentId - Unique agent identifier
|
|
94
|
+
* @param options - Workspace options
|
|
95
|
+
* @returns Workspace path information
|
|
96
|
+
*/ export function getWorkspacePath(taskId, agentId, options = {}) {
|
|
97
|
+
const sanitizedTaskId = sanitizeId(taskId);
|
|
98
|
+
const sanitizedAgentId = sanitizeId(agentId);
|
|
99
|
+
const workspaceRoot = options.workspaceRoot || WORKSPACE_ROOT;
|
|
100
|
+
const workspacePath = path.join(workspaceRoot, sanitizedTaskId, sanitizedAgentId);
|
|
101
|
+
const subdirectories = {
|
|
102
|
+
logs: path.join(workspacePath, 'logs'),
|
|
103
|
+
reports: path.join(workspacePath, 'reports'),
|
|
104
|
+
metrics: path.join(workspacePath, 'metrics'),
|
|
105
|
+
deliverables: path.join(workspacePath, 'deliverables')
|
|
106
|
+
};
|
|
107
|
+
return {
|
|
108
|
+
path: workspacePath,
|
|
109
|
+
taskId: sanitizedTaskId,
|
|
110
|
+
agentId: sanitizedAgentId,
|
|
111
|
+
subdirectories
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Write output to workspace
|
|
116
|
+
*
|
|
117
|
+
* Pattern: Atomic write with automatic directory creation
|
|
118
|
+
*
|
|
119
|
+
* @param workspace - Workspace path information
|
|
120
|
+
* @param type - Output type (logs, reports, metrics, deliverables)
|
|
121
|
+
* @param filename - Name of the output file
|
|
122
|
+
* @param content - Content to write (string or object)
|
|
123
|
+
* @returns Promise that resolves when write is complete
|
|
124
|
+
* @throws INVALID_INPUT if type is invalid
|
|
125
|
+
* @throws FILE_WRITE_FAILED if write fails
|
|
126
|
+
*/ export async function writeOutput(workspace, type, filename, content) {
|
|
127
|
+
// Validate type
|
|
128
|
+
const validTypes = [
|
|
129
|
+
'logs',
|
|
130
|
+
'reports',
|
|
131
|
+
'metrics',
|
|
132
|
+
'deliverables'
|
|
133
|
+
];
|
|
134
|
+
if (!validTypes.includes(type)) {
|
|
135
|
+
throw createError(ErrorCode.INVALID_INPUT, `Invalid output type. Must be one of: ${validTypes.join(', ')}`, {
|
|
136
|
+
type
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
// Sanitize filename
|
|
140
|
+
const sanitizedFilename = sanitizeFilename(filename);
|
|
141
|
+
const outputPath = path.join(workspace.subdirectories[type], sanitizedFilename);
|
|
142
|
+
// Ensure directory exists
|
|
143
|
+
await ensureDirectory(path.dirname(outputPath));
|
|
144
|
+
// Convert content to string if necessary
|
|
145
|
+
const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
|
|
146
|
+
// Atomic write
|
|
147
|
+
try {
|
|
148
|
+
await atomicWrite(outputPath, contentStr);
|
|
149
|
+
logger.debug('Output written', {
|
|
150
|
+
taskId: workspace.taskId,
|
|
151
|
+
agentId: workspace.agentId,
|
|
152
|
+
type,
|
|
153
|
+
filename: sanitizedFilename,
|
|
154
|
+
sizeBytes: contentStr.length
|
|
155
|
+
});
|
|
156
|
+
} catch (error) {
|
|
157
|
+
throw createError(ErrorCode.FILE_WRITE_FAILED, 'Failed to write output to workspace', {
|
|
158
|
+
taskId: workspace.taskId,
|
|
159
|
+
agentId: workspace.agentId,
|
|
160
|
+
type,
|
|
161
|
+
filename: sanitizedFilename,
|
|
162
|
+
error: error.message
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Read output from workspace
|
|
168
|
+
*
|
|
169
|
+
* @param workspace - Workspace path information
|
|
170
|
+
* @param type - Output type (logs, reports, metrics, deliverables)
|
|
171
|
+
* @param filename - Name of the output file
|
|
172
|
+
* @returns File content (parsed as JSON if applicable)
|
|
173
|
+
* @throws INVALID_INPUT if type is invalid
|
|
174
|
+
* @throws FILE_NOT_FOUND if file does not exist
|
|
175
|
+
*/ export async function readOutput(workspace, type, filename) {
|
|
176
|
+
// Validate type
|
|
177
|
+
const validTypes = [
|
|
178
|
+
'logs',
|
|
179
|
+
'reports',
|
|
180
|
+
'metrics',
|
|
181
|
+
'deliverables'
|
|
182
|
+
];
|
|
183
|
+
if (!validTypes.includes(type)) {
|
|
184
|
+
throw createError(ErrorCode.INVALID_INPUT, `Invalid output type. Must be one of: ${validTypes.join(', ')}`, {
|
|
185
|
+
type
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const sanitizedFilename = sanitizeFilename(filename);
|
|
189
|
+
const outputPath = path.join(workspace.subdirectories[type], sanitizedFilename);
|
|
190
|
+
try {
|
|
191
|
+
const fs = await import('fs/promises');
|
|
192
|
+
const content = await fs.readFile(outputPath, 'utf8');
|
|
193
|
+
// Try to parse as JSON
|
|
194
|
+
if (filename.endsWith('.json')) {
|
|
195
|
+
try {
|
|
196
|
+
return JSON.parse(content);
|
|
197
|
+
} catch {
|
|
198
|
+
// Return as string if JSON parsing fails
|
|
199
|
+
return content;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return content;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
const err = error;
|
|
205
|
+
if (err.code === 'ENOENT') {
|
|
206
|
+
throw createError(ErrorCode.FILE_NOT_FOUND, 'Output file not found', {
|
|
207
|
+
taskId: workspace.taskId,
|
|
208
|
+
agentId: workspace.agentId,
|
|
209
|
+
type,
|
|
210
|
+
filename: sanitizedFilename
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Signal agent completion
|
|
218
|
+
*
|
|
219
|
+
* Writes a completion signal file that coordinators can poll for.
|
|
220
|
+
*
|
|
221
|
+
* @param workspace - Workspace path information
|
|
222
|
+
* @param metadata - Completion metadata
|
|
223
|
+
* @returns Promise that resolves when signal is written
|
|
224
|
+
*/ export async function signalCompletion(workspace, metadata) {
|
|
225
|
+
await writeCompletionSignal(workspace, {
|
|
226
|
+
...metadata,
|
|
227
|
+
taskId: workspace.taskId,
|
|
228
|
+
agentId: workspace.agentId,
|
|
229
|
+
timestamp: new Date()
|
|
230
|
+
});
|
|
231
|
+
logger.info('Completion signal written', {
|
|
232
|
+
taskId: workspace.taskId,
|
|
233
|
+
agentId: workspace.agentId,
|
|
234
|
+
success: metadata.success,
|
|
235
|
+
confidence: metadata.confidence
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* List all workspaces for a task
|
|
240
|
+
*
|
|
241
|
+
* @param taskId - Task identifier
|
|
242
|
+
* @param options - Workspace options
|
|
243
|
+
* @returns Array of agent IDs with workspaces
|
|
244
|
+
*/ export async function listWorkspaces(taskId, options = {}) {
|
|
245
|
+
const sanitizedTaskId = sanitizeId(taskId);
|
|
246
|
+
const workspaceRoot = options.workspaceRoot || WORKSPACE_ROOT;
|
|
247
|
+
const taskPath = path.join(workspaceRoot, sanitizedTaskId);
|
|
248
|
+
try {
|
|
249
|
+
const fs = await import('fs/promises');
|
|
250
|
+
const entries = await fs.readdir(taskPath, {
|
|
251
|
+
withFileTypes: true
|
|
252
|
+
});
|
|
253
|
+
return entries.filter((entry)=>entry.isDirectory()).map((entry)=>entry.name);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
const err = error;
|
|
256
|
+
if (err.code === 'ENOENT') {
|
|
257
|
+
return [];
|
|
258
|
+
}
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Sanitize an ID to prevent path traversal
|
|
264
|
+
*
|
|
265
|
+
* @param id - Input ID
|
|
266
|
+
* @returns Sanitized ID
|
|
267
|
+
*/ function sanitizeId(id) {
|
|
268
|
+
// Remove path separators and special characters
|
|
269
|
+
return id.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Sanitize a filename to prevent path traversal
|
|
273
|
+
*
|
|
274
|
+
* @param filename - Input filename
|
|
275
|
+
* @returns Sanitized filename
|
|
276
|
+
*/ function sanitizeFilename(filename) {
|
|
277
|
+
// Remove path separators but keep dots for extensions
|
|
278
|
+
return path.basename(filename).replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
//# sourceMappingURL=agent-workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/agent-workspace.ts"],"sourcesContent":["/**\r\n * Agent Workspace Management\r\n *\r\n * Provides persistent, organized workspace for agent outputs with reliable completion signals.\r\n * Part of Task 2.1: Persistent Agent Output Workspace (Integration)\r\n *\r\n * Directory Structure:\r\n * artifacts/agent-workspaces/{task_id}/{agent_id}/\r\n * ├── logs/ (stdout.log, stderr.log)\r\n * ├── reports/ (analysis.json, etc.)\r\n * ├── metrics/ (performance.json, etc.)\r\n * ├── deliverables/ (output files)\r\n * └── COMPLETION_SIGNAL.json\r\n *\r\n * Usage:\r\n * const workspace = await createWorkspace('task-123', 'agent-456');\r\n * await writeOutput(workspace, 'logs', 'stdout.log', 'Log content');\r\n * await signalCompletion(workspace, { success: true, confidence: 0.85 });\r\n */\r\n\r\nimport * as path from 'path';\r\nimport { atomicWrite, ensureDirectory } from './file-operations.js';\r\nimport { createLogger } from './logging.js';\r\nimport { createError, ErrorCode } from './errors.js';\r\nimport { writeCompletionSignal, CompletionMetadata } from './completion-signal-handler.js';\r\n\r\nconst logger = createLogger('agent-workspace');\r\n\r\n/**\r\n * Workspace configuration\r\n */\r\nconst WORKSPACE_ROOT = path.resolve(process.cwd(), 'artifacts', 'agent-workspaces');\r\n\r\n/**\r\n * Output types supported by workspace\r\n */\r\nexport type OutputType = 'logs' | 'reports' | 'metrics' | 'deliverables';\r\n\r\n/**\r\n * Workspace path information\r\n */\r\nexport interface WorkspacePath {\r\n /** Root path of the workspace */\r\n path: string;\r\n /** Task ID */\r\n taskId: string;\r\n /** Agent ID */\r\n agentId: string;\r\n /** Paths to subdirectories */\r\n subdirectories: {\r\n logs: string;\r\n reports: string;\r\n metrics: string;\r\n deliverables: string;\r\n };\r\n}\r\n\r\n/**\r\n * Workspace creation options\r\n */\r\nexport interface WorkspaceOptions {\r\n /** Custom workspace root (default: artifacts/agent-workspaces) */\r\n workspaceRoot?: string;\r\n /** Skip directory creation (default: false) */\r\n skipCreate?: boolean;\r\n}\r\n\r\n/**\r\n * Create a workspace for an agent\r\n *\r\n * Pattern: Atomic directory creation with race-condition safety\r\n *\r\n * @param taskId - Unique task identifier\r\n * @param agentId - Unique agent identifier\r\n * @param options - Workspace creation options\r\n * @returns Workspace path information\r\n * @throws INVALID_INPUT if taskId or agentId is invalid\r\n * @throws DIRECTORY_CREATE_FAILED if directory creation fails\r\n */\r\nexport async function createWorkspace(\r\n taskId: string,\r\n agentId: string,\r\n options: WorkspaceOptions = {}\r\n): Promise<WorkspacePath> {\r\n // Validate inputs\r\n if (!taskId || typeof taskId !== 'string') {\r\n throw createError(\r\n ErrorCode.INVALID_INPUT,\r\n 'Task ID must be a non-empty string',\r\n { taskId }\r\n );\r\n }\r\n if (!agentId || typeof agentId !== 'string') {\r\n throw createError(\r\n ErrorCode.INVALID_INPUT,\r\n 'Agent ID must be a non-empty string',\r\n { agentId }\r\n );\r\n }\r\n\r\n // Sanitize IDs to prevent path traversal\r\n const sanitizedTaskId = sanitizeId(taskId);\r\n const sanitizedAgentId = sanitizeId(agentId);\r\n\r\n const workspaceRoot = options.workspaceRoot || WORKSPACE_ROOT;\r\n const workspacePath = path.join(workspaceRoot, sanitizedTaskId, sanitizedAgentId);\r\n\r\n // Define subdirectories\r\n const subdirectories = {\r\n logs: path.join(workspacePath, 'logs'),\r\n reports: path.join(workspacePath, 'reports'),\r\n metrics: path.join(workspacePath, 'metrics'),\r\n deliverables: path.join(workspacePath, 'deliverables'),\r\n };\r\n\r\n // Create directories (atomic, race-condition safe)\r\n if (!options.skipCreate) {\r\n try {\r\n await ensureDirectory(workspacePath);\r\n await Promise.all(\r\n Object.values(subdirectories).map((dir) => ensureDirectory(dir))\r\n );\r\n logger.info('Workspace created', { taskId, agentId, workspacePath });\r\n } catch (error) {\r\n throw createError(\r\n ErrorCode.DIRECTORY_CREATE_FAILED,\r\n 'Failed to create workspace directories',\r\n { taskId, agentId, workspacePath, error: (error as Error).message }\r\n );\r\n }\r\n }\r\n\r\n return {\r\n path: workspacePath,\r\n taskId: sanitizedTaskId,\r\n agentId: sanitizedAgentId,\r\n subdirectories,\r\n };\r\n}\r\n\r\n/**\r\n * Get the path to an existing workspace\r\n *\r\n * @param taskId - Unique task identifier\r\n * @param agentId - Unique agent identifier\r\n * @param options - Workspace options\r\n * @returns Workspace path information\r\n */\r\nexport function getWorkspacePath(\r\n taskId: string,\r\n agentId: string,\r\n options: WorkspaceOptions = {}\r\n): WorkspacePath {\r\n const sanitizedTaskId = sanitizeId(taskId);\r\n const sanitizedAgentId = sanitizeId(agentId);\r\n const workspaceRoot = options.workspaceRoot || WORKSPACE_ROOT;\r\n const workspacePath = path.join(workspaceRoot, sanitizedTaskId, sanitizedAgentId);\r\n\r\n const subdirectories = {\r\n logs: path.join(workspacePath, 'logs'),\r\n reports: path.join(workspacePath, 'reports'),\r\n metrics: path.join(workspacePath, 'metrics'),\r\n deliverables: path.join(workspacePath, 'deliverables'),\r\n };\r\n\r\n return {\r\n path: workspacePath,\r\n taskId: sanitizedTaskId,\r\n agentId: sanitizedAgentId,\r\n subdirectories,\r\n };\r\n}\r\n\r\n/**\r\n * Write output to workspace\r\n *\r\n * Pattern: Atomic write with automatic directory creation\r\n *\r\n * @param workspace - Workspace path information\r\n * @param type - Output type (logs, reports, metrics, deliverables)\r\n * @param filename - Name of the output file\r\n * @param content - Content to write (string or object)\r\n * @returns Promise that resolves when write is complete\r\n * @throws INVALID_INPUT if type is invalid\r\n * @throws FILE_WRITE_FAILED if write fails\r\n */\r\nexport async function writeOutput(\r\n workspace: WorkspacePath,\r\n type: OutputType,\r\n filename: string,\r\n content: string | Record<string, any>\r\n): Promise<void> {\r\n // Validate type\r\n const validTypes: OutputType[] = ['logs', 'reports', 'metrics', 'deliverables'];\r\n if (!validTypes.includes(type)) {\r\n throw createError(\r\n ErrorCode.INVALID_INPUT,\r\n `Invalid output type. Must be one of: ${validTypes.join(', ')}`,\r\n { type }\r\n );\r\n }\r\n\r\n // Sanitize filename\r\n const sanitizedFilename = sanitizeFilename(filename);\r\n const outputPath = path.join(workspace.subdirectories[type], sanitizedFilename);\r\n\r\n // Ensure directory exists\r\n await ensureDirectory(path.dirname(outputPath));\r\n\r\n // Convert content to string if necessary\r\n const contentStr =\r\n typeof content === 'string' ? content : JSON.stringify(content, null, 2);\r\n\r\n // Atomic write\r\n try {\r\n await atomicWrite(outputPath, contentStr);\r\n logger.debug('Output written', {\r\n taskId: workspace.taskId,\r\n agentId: workspace.agentId,\r\n type,\r\n filename: sanitizedFilename,\r\n sizeBytes: contentStr.length,\r\n });\r\n } catch (error) {\r\n throw createError(\r\n ErrorCode.FILE_WRITE_FAILED,\r\n 'Failed to write output to workspace',\r\n {\r\n taskId: workspace.taskId,\r\n agentId: workspace.agentId,\r\n type,\r\n filename: sanitizedFilename,\r\n error: (error as Error).message,\r\n }\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Read output from workspace\r\n *\r\n * @param workspace - Workspace path information\r\n * @param type - Output type (logs, reports, metrics, deliverables)\r\n * @param filename - Name of the output file\r\n * @returns File content (parsed as JSON if applicable)\r\n * @throws INVALID_INPUT if type is invalid\r\n * @throws FILE_NOT_FOUND if file does not exist\r\n */\r\nexport async function readOutput(\r\n workspace: WorkspacePath,\r\n type: OutputType,\r\n filename: string\r\n): Promise<string | Record<string, any>> {\r\n // Validate type\r\n const validTypes: OutputType[] = ['logs', 'reports', 'metrics', 'deliverables'];\r\n if (!validTypes.includes(type)) {\r\n throw createError(\r\n ErrorCode.INVALID_INPUT,\r\n `Invalid output type. Must be one of: ${validTypes.join(', ')}`,\r\n { type }\r\n );\r\n }\r\n\r\n const sanitizedFilename = sanitizeFilename(filename);\r\n const outputPath = path.join(workspace.subdirectories[type], sanitizedFilename);\r\n\r\n try {\r\n const fs = await import('fs/promises');\r\n const content = await fs.readFile(outputPath, 'utf8');\r\n\r\n // Try to parse as JSON\r\n if (filename.endsWith('.json')) {\r\n try {\r\n return JSON.parse(content);\r\n } catch {\r\n // Return as string if JSON parsing fails\r\n return content;\r\n }\r\n }\r\n\r\n return content;\r\n } catch (error) {\r\n const err = error as NodeJS.ErrnoException;\r\n if (err.code === 'ENOENT') {\r\n throw createError(\r\n ErrorCode.FILE_NOT_FOUND,\r\n 'Output file not found',\r\n {\r\n taskId: workspace.taskId,\r\n agentId: workspace.agentId,\r\n type,\r\n filename: sanitizedFilename,\r\n }\r\n );\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Signal agent completion\r\n *\r\n * Writes a completion signal file that coordinators can poll for.\r\n *\r\n * @param workspace - Workspace path information\r\n * @param metadata - Completion metadata\r\n * @returns Promise that resolves when signal is written\r\n */\r\nexport async function signalCompletion(\r\n workspace: WorkspacePath,\r\n metadata: CompletionMetadata\r\n): Promise<void> {\r\n await writeCompletionSignal(workspace, {\r\n ...metadata,\r\n taskId: workspace.taskId,\r\n agentId: workspace.agentId,\r\n timestamp: new Date(),\r\n });\r\n\r\n logger.info('Completion signal written', {\r\n taskId: workspace.taskId,\r\n agentId: workspace.agentId,\r\n success: metadata.success,\r\n confidence: metadata.confidence,\r\n });\r\n}\r\n\r\n/**\r\n * List all workspaces for a task\r\n *\r\n * @param taskId - Task identifier\r\n * @param options - Workspace options\r\n * @returns Array of agent IDs with workspaces\r\n */\r\nexport async function listWorkspaces(\r\n taskId: string,\r\n options: WorkspaceOptions = {}\r\n): Promise<string[]> {\r\n const sanitizedTaskId = sanitizeId(taskId);\r\n const workspaceRoot = options.workspaceRoot || WORKSPACE_ROOT;\r\n const taskPath = path.join(workspaceRoot, sanitizedTaskId);\r\n\r\n try {\r\n const fs = await import('fs/promises');\r\n const entries = await fs.readdir(taskPath, { withFileTypes: true });\r\n return entries\r\n .filter((entry) => entry.isDirectory())\r\n .map((entry) => entry.name);\r\n } catch (error) {\r\n const err = error as NodeJS.ErrnoException;\r\n if (err.code === 'ENOENT') {\r\n return [];\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Sanitize an ID to prevent path traversal\r\n *\r\n * @param id - Input ID\r\n * @returns Sanitized ID\r\n */\r\nfunction sanitizeId(id: string): string {\r\n // Remove path separators and special characters\r\n return id.replace(/[^a-zA-Z0-9_-]/g, '_');\r\n}\r\n\r\n/**\r\n * Sanitize a filename to prevent path traversal\r\n *\r\n * @param filename - Input filename\r\n * @returns Sanitized filename\r\n */\r\nfunction sanitizeFilename(filename: string): string {\r\n // Remove path separators but keep dots for extensions\r\n return path.basename(filename).replace(/[^a-zA-Z0-9._-]/g, '_');\r\n}\r\n"],"names":["path","atomicWrite","ensureDirectory","createLogger","createError","ErrorCode","writeCompletionSignal","logger","WORKSPACE_ROOT","resolve","process","cwd","createWorkspace","taskId","agentId","options","INVALID_INPUT","sanitizedTaskId","sanitizeId","sanitizedAgentId","workspaceRoot","workspacePath","join","subdirectories","logs","reports","metrics","deliverables","skipCreate","Promise","all","Object","values","map","dir","info","error","DIRECTORY_CREATE_FAILED","message","getWorkspacePath","writeOutput","workspace","type","filename","content","validTypes","includes","sanitizedFilename","sanitizeFilename","outputPath","dirname","contentStr","JSON","stringify","debug","sizeBytes","length","FILE_WRITE_FAILED","readOutput","fs","readFile","endsWith","parse","err","code","FILE_NOT_FOUND","signalCompletion","metadata","timestamp","Date","success","confidence","listWorkspaces","taskPath","entries","readdir","withFileTypes","filter","entry","isDirectory","name","id","replace","basename"],"mappings":"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"}
|