claude-flow-novice 2.15.3 → 2.15.5
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 +29 -6
- 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 +238 -29
- 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 +6 -2
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +34 -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 +29 -6
- 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 +238 -29
- 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 +6 -2
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +34 -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/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/config-manager.js +109 -91
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/conversation-fork-cleanup.js +201 -0
- package/dist/cli/conversation-fork-cleanup.js.map +1 -0
- package/dist/cli/conversation-fork.js +16 -3
- package/dist/cli/conversation-fork.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/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +405 -0
- package/docs/MEMORY_CLEANUP_GUIDE.md +358 -0
- package/docs/MEMORY_LEAK_FIX_SUMMARY.md +322 -0
- package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +319 -0
- package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +574 -0
- package/package.json +35 -4
- package/readme/README.md +53 -5
- 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/scripts/verify-redis-cleanup.sh +173 -0
- package/tests/README.md +84 -0
- package/tests/test-memory-leak-task-mode.sh +435 -0
- 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
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# deploy-approved-skill.sh - Deploy Approved Skill from Phase 4 Workflow Codification
|
|
4
|
+
#
|
|
5
|
+
# Purpose:
|
|
6
|
+
# After a workflow pattern is approved in Phase 4, this script deploys the generated
|
|
7
|
+
# skill into the Skills Database with proper approval tracking and agent mappings.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# deploy-approved-skill.sh PATTERN_ID SKILL_NAME CONTENT_PATH [CATEGORY] [TEAM_IDS]
|
|
11
|
+
#
|
|
12
|
+
# Parameters:
|
|
13
|
+
# PATTERN_ID - Phase 4 workflow pattern ID (numeric)
|
|
14
|
+
# SKILL_NAME - Skill name (e.g., "jwt-authentication")
|
|
15
|
+
# CONTENT_PATH - Path to skill markdown file
|
|
16
|
+
# CATEGORY - Category: domain, coordination, infrastructure, testing, foundation (default: domain)
|
|
17
|
+
# TEAM_IDS - Comma-separated agent types (e.g., "backend-developer,api-designer")
|
|
18
|
+
#
|
|
19
|
+
# Phase 4 Integration:
|
|
20
|
+
# After expert approves workflow pattern in Phase 4:
|
|
21
|
+
#
|
|
22
|
+
# ./.claude/skills/workflow-codification/deploy-approved-skill.sh \
|
|
23
|
+
# "$PATTERN_ID" \
|
|
24
|
+
# "$SKILL_NAME" \
|
|
25
|
+
# "$CONTENT_PATH" \
|
|
26
|
+
# "$CATEGORY" \
|
|
27
|
+
# "$TEAM_IDS"
|
|
28
|
+
#
|
|
29
|
+
# Example:
|
|
30
|
+
# ./.claude/skills/workflow-codification/deploy-approved-skill.sh \
|
|
31
|
+
# "42" \
|
|
32
|
+
# "jwt-authentication" \
|
|
33
|
+
# ".claude/skills/auth/jwt-auth.md" \
|
|
34
|
+
# "domain" \
|
|
35
|
+
# "backend-developer,api-designer"
|
|
36
|
+
#
|
|
37
|
+
# Exit Codes:
|
|
38
|
+
# 0 - Success
|
|
39
|
+
# 1 - Invalid parameters
|
|
40
|
+
# 2 - File not found
|
|
41
|
+
# 3 - Database error
|
|
42
|
+
# 4 - PostgreSQL connection error (warning only, continues)
|
|
43
|
+
#
|
|
44
|
+
# Environment Variables:
|
|
45
|
+
# CFN_SKILLS_DB_PATH - Path to Skills DB (default: ./.claude/skills-database/skills.db)
|
|
46
|
+
# PHASE4_POSTGRES_HOST - PostgreSQL host for Phase 4 (optional)
|
|
47
|
+
# PHASE4_POSTGRES_DB - PostgreSQL database name (default: workflow_codification)
|
|
48
|
+
# PHASE4_POSTGRES_USER - PostgreSQL username (optional)
|
|
49
|
+
# PHASE4_POSTGRES_PASS - PostgreSQL password (optional)
|
|
50
|
+
|
|
51
|
+
set -euo pipefail
|
|
52
|
+
|
|
53
|
+
# Configuration
|
|
54
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
55
|
+
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
|
56
|
+
|
|
57
|
+
# Source security utilities (SQL escaping, secure credentials)
|
|
58
|
+
source "${SCRIPT_DIR}/lib/security-utils.sh"
|
|
59
|
+
|
|
60
|
+
# Skills Database (SQLite - required)
|
|
61
|
+
CFN_SKILLS_DB_PATH="${CFN_SKILLS_DB_PATH:-./.claude/skills-database/skills.db}"
|
|
62
|
+
|
|
63
|
+
# Phase 4 PostgreSQL (optional)
|
|
64
|
+
PHASE4_POSTGRES_HOST="${PHASE4_POSTGRES_HOST:-}"
|
|
65
|
+
PHASE4_POSTGRES_DB="${PHASE4_POSTGRES_DB:-workflow_codification}"
|
|
66
|
+
PHASE4_POSTGRES_USER="${PHASE4_POSTGRES_USER:-}"
|
|
67
|
+
PHASE4_POSTGRES_PASS="${PHASE4_POSTGRES_PASS:-}"
|
|
68
|
+
|
|
69
|
+
# Color codes
|
|
70
|
+
RED='\033[0;31m'
|
|
71
|
+
GREEN='\033[0;32m'
|
|
72
|
+
YELLOW='\033[1;33m'
|
|
73
|
+
BLUE='\033[0;34m'
|
|
74
|
+
NC='\033[0m'
|
|
75
|
+
|
|
76
|
+
#######################################
|
|
77
|
+
# Utility functions
|
|
78
|
+
#######################################
|
|
79
|
+
log_info() {
|
|
80
|
+
echo -e "${BLUE}[INFO]${NC} $*" >&2
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
log_success() {
|
|
84
|
+
echo -e "${GREEN}[SUCCESS]${NC} $*" >&2
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
log_error() {
|
|
88
|
+
echo -e "${RED}[ERROR]${NC} $*" >&2
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
log_warning() {
|
|
92
|
+
echo -e "${YELLOW}[WARNING]${NC} $*" >&2
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
error_exit() {
|
|
96
|
+
local exit_code="$1"
|
|
97
|
+
shift
|
|
98
|
+
log_error "$@"
|
|
99
|
+
exit "$exit_code"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#######################################
|
|
103
|
+
# Validation functions
|
|
104
|
+
#######################################
|
|
105
|
+
validate_inputs() {
|
|
106
|
+
local pattern_id="$1"
|
|
107
|
+
local skill_name="$2"
|
|
108
|
+
local content_path="$3"
|
|
109
|
+
local category="$4"
|
|
110
|
+
|
|
111
|
+
# Validate required parameters
|
|
112
|
+
if [[ -z "$pattern_id" ]] || [[ -z "$skill_name" ]] || [[ -z "$content_path" ]]; then
|
|
113
|
+
echo "[ERROR] Missing required parameters" >&2
|
|
114
|
+
echo "Usage: deploy-approved-skill.sh PATTERN_ID SKILL_NAME CONTENT_PATH [CATEGORY] [TEAM_IDS]" >&2
|
|
115
|
+
echo "" >&2
|
|
116
|
+
echo "Example:" >&2
|
|
117
|
+
echo " deploy-approved-skill.sh 42 jwt-authentication ./skill.md domain backend-developer" >&2
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# Validate PATTERN_ID is numeric
|
|
122
|
+
if ! [[ "$pattern_id" =~ ^[0-9]+$ ]]; then
|
|
123
|
+
echo "[ERROR] PATTERN_ID must be numeric: $pattern_id" >&2
|
|
124
|
+
exit 1
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Validate skill name (security: prevent injection)
|
|
128
|
+
validate_skill_name "$skill_name" || exit 1
|
|
129
|
+
|
|
130
|
+
# Validate category (security: whitelist only)
|
|
131
|
+
validate_category "$category" || exit 1
|
|
132
|
+
|
|
133
|
+
# Validate content file exists
|
|
134
|
+
if [[ ! -f "$content_path" ]]; then
|
|
135
|
+
echo "[ERROR] Content file not found: $content_path" >&2
|
|
136
|
+
exit 2
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
# Validate content file is readable
|
|
140
|
+
if [[ ! -r "$content_path" ]]; then
|
|
141
|
+
echo "[ERROR] Content file is not readable: $content_path" >&2
|
|
142
|
+
echo "Check file permissions." >&2
|
|
143
|
+
exit 2
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
# Validate file path (security: prevent traversal)
|
|
147
|
+
validate_file_path "$content_path" "$PROJECT_ROOT" || exit 1
|
|
148
|
+
|
|
149
|
+
# Validate database exists
|
|
150
|
+
if [[ ! -f "$CFN_SKILLS_DB_PATH" ]]; then
|
|
151
|
+
echo "[ERROR] Skills database not found: $CFN_SKILLS_DB_PATH" >&2
|
|
152
|
+
echo "Run schema initialization first." >&2
|
|
153
|
+
exit 3
|
|
154
|
+
fi
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#######################################
|
|
158
|
+
# Calculate content hash
|
|
159
|
+
#######################################
|
|
160
|
+
calculate_content_hash() {
|
|
161
|
+
local content_path="$1"
|
|
162
|
+
|
|
163
|
+
if command -v sha256sum &> /dev/null; then
|
|
164
|
+
sha256sum "$content_path" | awk '{print $1}'
|
|
165
|
+
elif command -v shasum &> /dev/null; then
|
|
166
|
+
shasum -a 256 "$content_path" | awk '{print $1}'
|
|
167
|
+
else
|
|
168
|
+
error_exit 3 "Neither sha256sum nor shasum found. Cannot calculate content hash."
|
|
169
|
+
fi
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
#######################################
|
|
173
|
+
# Determine approval level based on category
|
|
174
|
+
#######################################
|
|
175
|
+
determine_approval_level() {
|
|
176
|
+
local category="$1"
|
|
177
|
+
|
|
178
|
+
case "$category" in
|
|
179
|
+
coordination|foundation|testing)
|
|
180
|
+
echo "auto"
|
|
181
|
+
;;
|
|
182
|
+
infrastructure)
|
|
183
|
+
echo "escalate"
|
|
184
|
+
;;
|
|
185
|
+
domain)
|
|
186
|
+
echo "human"
|
|
187
|
+
;;
|
|
188
|
+
*)
|
|
189
|
+
# Default to human review for unknown categories
|
|
190
|
+
echo "human"
|
|
191
|
+
;;
|
|
192
|
+
esac
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#######################################
|
|
196
|
+
# Insert skill into Skills DB
|
|
197
|
+
#######################################
|
|
198
|
+
insert_skill() {
|
|
199
|
+
local pattern_id="$1"
|
|
200
|
+
local skill_name="$2"
|
|
201
|
+
local content_path="$3"
|
|
202
|
+
local category="$4"
|
|
203
|
+
local content_hash="$5"
|
|
204
|
+
local approval_level="$6"
|
|
205
|
+
|
|
206
|
+
log_info "Inserting skill into database: $skill_name"
|
|
207
|
+
|
|
208
|
+
# Generate version (default: 1.0.0 for new skills)
|
|
209
|
+
local version="1.0.0"
|
|
210
|
+
|
|
211
|
+
# SECURITY FIX: Escape all SQL strings to prevent injection
|
|
212
|
+
local safe_skill_name
|
|
213
|
+
safe_skill_name=$(escape_sql_string "$skill_name")
|
|
214
|
+
local safe_content_path
|
|
215
|
+
safe_content_path=$(escape_sql_string "$content_path")
|
|
216
|
+
local safe_category
|
|
217
|
+
safe_category=$(escape_sql_string "$category")
|
|
218
|
+
local safe_content_hash
|
|
219
|
+
safe_content_hash=$(escape_sql_string "$content_hash")
|
|
220
|
+
local safe_approval_level
|
|
221
|
+
safe_approval_level=$(escape_sql_string "$approval_level")
|
|
222
|
+
|
|
223
|
+
# Check if skill already exists
|
|
224
|
+
local existing_count
|
|
225
|
+
existing_count=$(sqlite3 "$CFN_SKILLS_DB_PATH" "SELECT COUNT(*) FROM skills WHERE name = '${safe_skill_name}';")
|
|
226
|
+
|
|
227
|
+
if [ "$existing_count" -gt 0 ]; then
|
|
228
|
+
log_warning "Skill '$skill_name' already exists. Updating instead of inserting."
|
|
229
|
+
|
|
230
|
+
# Update existing skill (with escaped values)
|
|
231
|
+
sqlite3 "$CFN_SKILLS_DB_PATH" <<EOF
|
|
232
|
+
UPDATE skills SET
|
|
233
|
+
category = '${safe_category}',
|
|
234
|
+
content_path = '${safe_content_path}',
|
|
235
|
+
content_hash = '${safe_content_hash}',
|
|
236
|
+
approval_level = '${safe_approval_level}',
|
|
237
|
+
phase4_pattern_id = ${pattern_id},
|
|
238
|
+
generated_by = 'phase4',
|
|
239
|
+
is_auto_generated = 1,
|
|
240
|
+
status = 'active',
|
|
241
|
+
updated_at = datetime('now')
|
|
242
|
+
WHERE name = '${safe_skill_name}';
|
|
243
|
+
EOF
|
|
244
|
+
|
|
245
|
+
# Get existing skill ID
|
|
246
|
+
sqlite3 "$CFN_SKILLS_DB_PATH" "SELECT id FROM skills WHERE name = '${safe_skill_name}';"
|
|
247
|
+
else
|
|
248
|
+
# Insert new skill (with escaped values)
|
|
249
|
+
sqlite3 "$CFN_SKILLS_DB_PATH" <<EOF
|
|
250
|
+
INSERT INTO skills (
|
|
251
|
+
name,
|
|
252
|
+
category,
|
|
253
|
+
content_path,
|
|
254
|
+
content_hash,
|
|
255
|
+
version,
|
|
256
|
+
status,
|
|
257
|
+
approval_level,
|
|
258
|
+
phase4_pattern_id,
|
|
259
|
+
generated_by,
|
|
260
|
+
is_auto_generated,
|
|
261
|
+
created_at,
|
|
262
|
+
updated_at
|
|
263
|
+
) VALUES (
|
|
264
|
+
'${safe_skill_name}',
|
|
265
|
+
'${safe_category}',
|
|
266
|
+
'${safe_content_path}',
|
|
267
|
+
'${safe_content_hash}',
|
|
268
|
+
'${version}',
|
|
269
|
+
'active',
|
|
270
|
+
'${safe_approval_level}',
|
|
271
|
+
${pattern_id},
|
|
272
|
+
'phase4',
|
|
273
|
+
1,
|
|
274
|
+
datetime('now'),
|
|
275
|
+
datetime('now')
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
SELECT last_insert_rowid();
|
|
279
|
+
EOF
|
|
280
|
+
fi
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
#######################################
|
|
284
|
+
# Record approval decision
|
|
285
|
+
#######################################
|
|
286
|
+
record_approval() {
|
|
287
|
+
local skill_id="$1"
|
|
288
|
+
local approval_level="$2"
|
|
289
|
+
local version="$3"
|
|
290
|
+
|
|
291
|
+
log_info "Recording approval decision for skill ID: $skill_id"
|
|
292
|
+
|
|
293
|
+
local reasoning="Auto-approved by Phase 4 workflow codification system after expert review"
|
|
294
|
+
|
|
295
|
+
# SECURITY FIX: Escape SQL strings
|
|
296
|
+
local safe_version
|
|
297
|
+
safe_version=$(escape_sql_string "$version")
|
|
298
|
+
local safe_approval_level
|
|
299
|
+
safe_approval_level=$(escape_sql_string "$approval_level")
|
|
300
|
+
local safe_reasoning
|
|
301
|
+
safe_reasoning=$(escape_sql_string "$reasoning")
|
|
302
|
+
|
|
303
|
+
sqlite3 "$CFN_SKILLS_DB_PATH" <<EOF
|
|
304
|
+
INSERT INTO approval_history (
|
|
305
|
+
skill_id,
|
|
306
|
+
version,
|
|
307
|
+
approval_level,
|
|
308
|
+
approver,
|
|
309
|
+
decision,
|
|
310
|
+
reasoning,
|
|
311
|
+
timestamp
|
|
312
|
+
) VALUES (
|
|
313
|
+
${skill_id},
|
|
314
|
+
'${safe_version}',
|
|
315
|
+
'${safe_approval_level}',
|
|
316
|
+
'phase4-system',
|
|
317
|
+
'approved',
|
|
318
|
+
'${safe_reasoning}',
|
|
319
|
+
datetime('now')
|
|
320
|
+
);
|
|
321
|
+
EOF
|
|
322
|
+
|
|
323
|
+
# Update skill's last approval metadata
|
|
324
|
+
sqlite3 "$CFN_SKILLS_DB_PATH" <<EOF
|
|
325
|
+
UPDATE skills SET
|
|
326
|
+
last_approved_by = 'phase4-system',
|
|
327
|
+
last_approval_date = datetime('now')
|
|
328
|
+
WHERE id = ${skill_id};
|
|
329
|
+
EOF
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
#######################################
|
|
333
|
+
# Create agent mappings
|
|
334
|
+
#######################################
|
|
335
|
+
create_agent_mappings() {
|
|
336
|
+
local skill_id="$1"
|
|
337
|
+
local team_ids="$2"
|
|
338
|
+
|
|
339
|
+
if [ -z "$team_ids" ]; then
|
|
340
|
+
log_info "No agent mappings specified (TEAM_IDS empty)"
|
|
341
|
+
return 0
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
log_info "Creating agent skill mappings"
|
|
345
|
+
|
|
346
|
+
# Split comma-separated team IDs
|
|
347
|
+
local -a AGENTS
|
|
348
|
+
IFS=',' read -ra AGENTS <<< "$team_ids"
|
|
349
|
+
|
|
350
|
+
local mapping_count=0
|
|
351
|
+
for agent_type in "${AGENTS[@]}"; do
|
|
352
|
+
# Trim whitespace
|
|
353
|
+
agent_type=$(echo "$agent_type" | xargs)
|
|
354
|
+
|
|
355
|
+
if [ -z "$agent_type" ]; then
|
|
356
|
+
continue
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
# SECURITY FIX: Validate agent type (alphanumeric, hyphen, underscore only)
|
|
360
|
+
if ! [[ "$agent_type" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
361
|
+
log_error "Invalid agent type: $agent_type (must contain only letters, numbers, underscore, hyphen)"
|
|
362
|
+
continue
|
|
363
|
+
fi
|
|
364
|
+
|
|
365
|
+
log_info " - Mapping to agent: $agent_type"
|
|
366
|
+
|
|
367
|
+
# SECURITY FIX: Escape SQL string
|
|
368
|
+
local safe_agent_type
|
|
369
|
+
safe_agent_type=$(escape_sql_string "$agent_type")
|
|
370
|
+
|
|
371
|
+
# Check if mapping already exists
|
|
372
|
+
local existing_mapping
|
|
373
|
+
existing_mapping=$(sqlite3 "$CFN_SKILLS_DB_PATH" "SELECT COUNT(*) FROM agent_skill_mappings WHERE agent_type = '${safe_agent_type}' AND skill_id = ${skill_id};")
|
|
374
|
+
|
|
375
|
+
if [ "$existing_mapping" -gt 0 ]; then
|
|
376
|
+
log_warning " Mapping already exists for $agent_type, skipping"
|
|
377
|
+
continue
|
|
378
|
+
fi
|
|
379
|
+
|
|
380
|
+
# Insert mapping (with escaped values)
|
|
381
|
+
sqlite3 "$CFN_SKILLS_DB_PATH" "INSERT INTO agent_skill_mappings (agent_type, skill_id, priority, required, conditions, enabled, created_at, updated_at) VALUES ('${safe_agent_type}', ${skill_id}, 5, 0, '{\"taskContext\": [\"automation\"], \"phase\": \"loop3\"}', 1, datetime('now'), datetime('now'));" || {
|
|
382
|
+
log_error "Failed to insert mapping for $agent_type"
|
|
383
|
+
return 3
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
mapping_count=$((mapping_count + 1))
|
|
387
|
+
done
|
|
388
|
+
|
|
389
|
+
log_info "Created $mapping_count agent skill mappings"
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
#######################################
|
|
393
|
+
# Update Phase 4 status (PostgreSQL - optional)
|
|
394
|
+
#######################################
|
|
395
|
+
update_phase4_status() {
|
|
396
|
+
local pattern_id="$1"
|
|
397
|
+
local skill_id="$2"
|
|
398
|
+
|
|
399
|
+
# Check if PostgreSQL is configured
|
|
400
|
+
if [ -z "$PHASE4_POSTGRES_HOST" ] || [ -z "$PHASE4_POSTGRES_USER" ]; then
|
|
401
|
+
log_warning "PostgreSQL not configured, skipping Phase 4 status update"
|
|
402
|
+
return 0
|
|
403
|
+
fi
|
|
404
|
+
|
|
405
|
+
log_info "Updating Phase 4 workflow pattern status"
|
|
406
|
+
|
|
407
|
+
# SECURITY FIX #2: Quote all parameters to prevent command injection
|
|
408
|
+
# SECURITY FIX #3: Use .pgpass file instead of PGPASSWORD environment variable
|
|
409
|
+
local pgpass_file=""
|
|
410
|
+
if [ -n "$PHASE4_POSTGRES_PASS" ]; then
|
|
411
|
+
pgpass_file=$(create_pgpass_file "$PHASE4_POSTGRES_HOST" "5432" "$PHASE4_POSTGRES_DB" "$PHASE4_POSTGRES_USER" "$PHASE4_POSTGRES_PASS")
|
|
412
|
+
if [ -z "$pgpass_file" ]; then
|
|
413
|
+
log_warning "Failed to create .pgpass file, skipping Phase 4 update"
|
|
414
|
+
return 4
|
|
415
|
+
fi
|
|
416
|
+
export PGPASSFILE="$pgpass_file"
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
# Try to update Phase 4 status (with properly quoted parameters)
|
|
420
|
+
if psql -h "$PHASE4_POSTGRES_HOST" -U "$PHASE4_POSTGRES_USER" -d "$PHASE4_POSTGRES_DB" -t -A -c "UPDATE workflow_patterns SET status = 'deployed', deployed_skill_id = ${skill_id} WHERE id = ${pattern_id};" 2>/dev/null; then
|
|
421
|
+
log_success "Phase 4 status updated successfully"
|
|
422
|
+
else
|
|
423
|
+
log_warning "Failed to update Phase 4 status (pattern ID: $pattern_id). This is non-fatal."
|
|
424
|
+
return 4
|
|
425
|
+
fi
|
|
426
|
+
|
|
427
|
+
# Clean up is automatic via trap in create_pgpass_file()
|
|
428
|
+
unset PGPASSFILE
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
#######################################
|
|
432
|
+
# Main deployment logic
|
|
433
|
+
#######################################
|
|
434
|
+
main() {
|
|
435
|
+
# Parse parameters
|
|
436
|
+
local pattern_id="${1:-}"
|
|
437
|
+
local skill_name="${2:-}"
|
|
438
|
+
local content_path="${3:-}"
|
|
439
|
+
local category="${4:-domain}"
|
|
440
|
+
local team_ids="${5:-}"
|
|
441
|
+
|
|
442
|
+
log_info "========================================="
|
|
443
|
+
log_info "Deploy Approved Skill from Phase 4"
|
|
444
|
+
log_info "========================================="
|
|
445
|
+
log_info "Pattern ID: $pattern_id"
|
|
446
|
+
log_info "Skill Name: $skill_name"
|
|
447
|
+
log_info "Content Path: $content_path"
|
|
448
|
+
log_info "Category: $category"
|
|
449
|
+
log_info "Team IDs: ${team_ids:-<none>}"
|
|
450
|
+
log_info "========================================="
|
|
451
|
+
|
|
452
|
+
# Step 1: Validate inputs (including security checks)
|
|
453
|
+
validate_inputs "$pattern_id" "$skill_name" "$content_path" "$category"
|
|
454
|
+
log_success "Input validation passed"
|
|
455
|
+
|
|
456
|
+
# Step 2: Calculate content hash
|
|
457
|
+
local content_hash
|
|
458
|
+
content_hash=$(calculate_content_hash "$content_path")
|
|
459
|
+
log_success "Content hash calculated: $content_hash"
|
|
460
|
+
|
|
461
|
+
# Step 3: Determine approval level
|
|
462
|
+
local approval_level
|
|
463
|
+
approval_level=$(determine_approval_level "$category")
|
|
464
|
+
log_success "Approval level determined: $approval_level (category: $category)"
|
|
465
|
+
|
|
466
|
+
# Step 4: Insert skill into database
|
|
467
|
+
local skill_id
|
|
468
|
+
skill_id=$(insert_skill "$pattern_id" "$skill_name" "$content_path" "$category" "$content_hash" "$approval_level")
|
|
469
|
+
|
|
470
|
+
# Remove any whitespace/newlines from skill_id
|
|
471
|
+
skill_id=$(echo "$skill_id" | tr -d '[:space:]')
|
|
472
|
+
|
|
473
|
+
if [ -z "$skill_id" ]; then
|
|
474
|
+
error_exit 3 "Failed to insert skill into database"
|
|
475
|
+
fi
|
|
476
|
+
|
|
477
|
+
log_success "Skill inserted/updated with ID: $skill_id"
|
|
478
|
+
|
|
479
|
+
# Step 5: Record approval decision
|
|
480
|
+
record_approval "$skill_id" "$approval_level" "1.0.0"
|
|
481
|
+
log_success "Approval decision recorded"
|
|
482
|
+
|
|
483
|
+
# Step 6: Create agent mappings
|
|
484
|
+
if [ -n "$team_ids" ]; then
|
|
485
|
+
create_agent_mappings "$skill_id" "$team_ids"
|
|
486
|
+
log_success "Agent mappings created"
|
|
487
|
+
fi
|
|
488
|
+
|
|
489
|
+
# Step 7: Update Phase 4 status (optional)
|
|
490
|
+
update_phase4_status "$pattern_id" "$skill_id" || true
|
|
491
|
+
|
|
492
|
+
# Step 8: Output success message
|
|
493
|
+
log_info "========================================="
|
|
494
|
+
log_success "Deployment Complete!"
|
|
495
|
+
log_info "========================================="
|
|
496
|
+
log_info "Skill ID: $skill_id"
|
|
497
|
+
log_info "Skill Name: $skill_name"
|
|
498
|
+
log_info "Approval Level: $approval_level"
|
|
499
|
+
log_info "Category: $category"
|
|
500
|
+
|
|
501
|
+
if [ -n "$team_ids" ]; then
|
|
502
|
+
log_info "Mapped Agent Types: $team_ids"
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
log_info "========================================="
|
|
506
|
+
|
|
507
|
+
# Output skill ID for programmatic use
|
|
508
|
+
echo "$skill_id"
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
# Execute main function
|
|
512
|
+
main "$@"
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# security-utils.sh - Security utilities for bash scripts
|
|
4
|
+
#
|
|
5
|
+
# Purpose:
|
|
6
|
+
# Provide SQL escaping and secure credential handling for deployment scripts
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# source ./lib/security-utils.sh
|
|
10
|
+
# escaped=$(escape_sql_string "user's input")
|
|
11
|
+
# pgpass_file=$(create_pgpass_file "$host" "$port" "$db" "$user" "$pass")
|
|
12
|
+
|
|
13
|
+
#######################################
|
|
14
|
+
# Escape SQL string for SQLite
|
|
15
|
+
# Prevents SQL injection by doubling single quotes
|
|
16
|
+
#
|
|
17
|
+
# Arguments:
|
|
18
|
+
# $1 - String to escape
|
|
19
|
+
# Outputs:
|
|
20
|
+
# Escaped string safe for SQL
|
|
21
|
+
#######################################
|
|
22
|
+
escape_sql_string() {
|
|
23
|
+
local input="$1"
|
|
24
|
+
# Double all single quotes (SQLite standard escaping)
|
|
25
|
+
echo "${input//\'/\'\'}"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#######################################
|
|
29
|
+
# Escape SQL identifier (table/column name)
|
|
30
|
+
# Validates identifier contains only safe characters
|
|
31
|
+
#
|
|
32
|
+
# Arguments:
|
|
33
|
+
# $1 - Identifier to validate
|
|
34
|
+
# Outputs:
|
|
35
|
+
# Original identifier if safe
|
|
36
|
+
# Returns:
|
|
37
|
+
# 1 if identifier contains unsafe characters
|
|
38
|
+
#######################################
|
|
39
|
+
escape_sql_identifier() {
|
|
40
|
+
local identifier="$1"
|
|
41
|
+
|
|
42
|
+
# Allow only alphanumeric, underscore, hyphen
|
|
43
|
+
if [[ ! "$identifier" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
44
|
+
echo "[ERROR] Invalid SQL identifier: $identifier" >&2
|
|
45
|
+
echo "[ERROR] Identifiers must contain only letters, numbers, underscore, hyphen" >&2
|
|
46
|
+
return 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
echo "$identifier"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#######################################
|
|
53
|
+
# Create temporary .pgpass file for secure PostgreSQL authentication
|
|
54
|
+
# Automatically cleaned up on script exit
|
|
55
|
+
#
|
|
56
|
+
# Arguments:
|
|
57
|
+
# $1 - hostname
|
|
58
|
+
# $2 - port (default: 5432)
|
|
59
|
+
# $3 - database
|
|
60
|
+
# $4 - username
|
|
61
|
+
# $5 - password
|
|
62
|
+
# Outputs:
|
|
63
|
+
# Path to temporary .pgpass file
|
|
64
|
+
# Returns:
|
|
65
|
+
# 0 on success, 1 on failure
|
|
66
|
+
#######################################
|
|
67
|
+
create_pgpass_file() {
|
|
68
|
+
local host="$1"
|
|
69
|
+
local port="${2:-5432}"
|
|
70
|
+
local database="$3"
|
|
71
|
+
local username="$4"
|
|
72
|
+
local password="$5"
|
|
73
|
+
|
|
74
|
+
# Create temporary .pgpass file
|
|
75
|
+
local pgpass_file
|
|
76
|
+
pgpass_file=$(mktemp)
|
|
77
|
+
|
|
78
|
+
# Write credentials in PostgreSQL .pgpass format
|
|
79
|
+
# Format: hostname:port:database:username:password
|
|
80
|
+
echo "${host}:${port}:${database}:${username}:${password}" > "$pgpass_file"
|
|
81
|
+
|
|
82
|
+
# Set strict permissions (required by PostgreSQL)
|
|
83
|
+
chmod 600 "$pgpass_file" || {
|
|
84
|
+
echo "[ERROR] Failed to set .pgpass file permissions" >&2
|
|
85
|
+
rm -f "$pgpass_file"
|
|
86
|
+
return 1
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Register cleanup on script exit
|
|
90
|
+
trap "secure_cleanup_pgpass '$pgpass_file'" EXIT INT TERM
|
|
91
|
+
|
|
92
|
+
echo "$pgpass_file"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#######################################
|
|
96
|
+
# Securely clean up .pgpass file
|
|
97
|
+
# Shreds file contents before deletion
|
|
98
|
+
#
|
|
99
|
+
# Arguments:
|
|
100
|
+
# $1 - Path to .pgpass file
|
|
101
|
+
#######################################
|
|
102
|
+
secure_cleanup_pgpass() {
|
|
103
|
+
local pgpass_file="$1"
|
|
104
|
+
|
|
105
|
+
if [ -f "$pgpass_file" ]; then
|
|
106
|
+
# Shred file if available (overwrites content)
|
|
107
|
+
if command -v shred &> /dev/null; then
|
|
108
|
+
shred -u "$pgpass_file" 2>/dev/null || rm -f "$pgpass_file"
|
|
109
|
+
else
|
|
110
|
+
# Fallback: overwrite then delete
|
|
111
|
+
dd if=/dev/zero of="$pgpass_file" bs=1k count=1 2>/dev/null || true
|
|
112
|
+
rm -f "$pgpass_file"
|
|
113
|
+
fi
|
|
114
|
+
fi
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#######################################
|
|
118
|
+
# Validate category against whitelist
|
|
119
|
+
# Prevents approval bypass via invalid categories
|
|
120
|
+
#
|
|
121
|
+
# Arguments:
|
|
122
|
+
# $1 - Category to validate
|
|
123
|
+
# Returns:
|
|
124
|
+
# 0 if valid, 1 if invalid
|
|
125
|
+
#######################################
|
|
126
|
+
validate_category() {
|
|
127
|
+
local category="$1"
|
|
128
|
+
|
|
129
|
+
case "$category" in
|
|
130
|
+
coordination|domain|infrastructure|testing|foundation)
|
|
131
|
+
return 0
|
|
132
|
+
;;
|
|
133
|
+
*)
|
|
134
|
+
echo "[ERROR] Invalid category: $category" >&2
|
|
135
|
+
echo "[ERROR] Allowed: coordination, domain, infrastructure, testing, foundation" >&2
|
|
136
|
+
return 1
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#######################################
|
|
142
|
+
# Validate skill name against security constraints
|
|
143
|
+
# Prevents path traversal and special character injection
|
|
144
|
+
#
|
|
145
|
+
# Arguments:
|
|
146
|
+
# $1 - Skill name to validate
|
|
147
|
+
# Returns:
|
|
148
|
+
# 0 if valid, 1 if invalid
|
|
149
|
+
#######################################
|
|
150
|
+
validate_skill_name() {
|
|
151
|
+
local skill_name="$1"
|
|
152
|
+
|
|
153
|
+
# Check for path traversal
|
|
154
|
+
if [[ "$skill_name" == *".."* ]] || [[ "$skill_name" == *"/"* ]]; then
|
|
155
|
+
echo "[ERROR] Skill name contains path traversal: $skill_name" >&2
|
|
156
|
+
return 1
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
# Allow alphanumeric, hyphen, underscore only
|
|
160
|
+
if [[ ! "$skill_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
161
|
+
echo "[ERROR] Invalid skill name: $skill_name" >&2
|
|
162
|
+
echo "[ERROR] Skill names must contain only letters, numbers, underscore, hyphen" >&2
|
|
163
|
+
return 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
return 0
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
#######################################
|
|
170
|
+
# Validate file path is within allowed directory
|
|
171
|
+
# Prevents path traversal attacks
|
|
172
|
+
#
|
|
173
|
+
# Arguments:
|
|
174
|
+
# $1 - File path to validate
|
|
175
|
+
# $2 - Allowed base directory (default: current directory)
|
|
176
|
+
# Returns:
|
|
177
|
+
# 0 if valid, 1 if invalid
|
|
178
|
+
#######################################
|
|
179
|
+
validate_file_path() {
|
|
180
|
+
local file_path="$1"
|
|
181
|
+
local base_dir="${2:-.}"
|
|
182
|
+
|
|
183
|
+
# Resolve to absolute path
|
|
184
|
+
local abs_path
|
|
185
|
+
abs_path=$(readlink -f "$file_path" 2>/dev/null) || {
|
|
186
|
+
echo "[ERROR] Cannot resolve file path: $file_path" >&2
|
|
187
|
+
return 1
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
local abs_base
|
|
191
|
+
abs_base=$(readlink -f "$base_dir" 2>/dev/null) || {
|
|
192
|
+
echo "[ERROR] Cannot resolve base directory: $base_dir" >&2
|
|
193
|
+
return 1
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# Check if file is within base directory
|
|
197
|
+
if [[ ! "$abs_path" =~ ^"$abs_base" ]]; then
|
|
198
|
+
echo "[ERROR] File path outside allowed directory: $file_path" >&2
|
|
199
|
+
echo "[ERROR] Base directory: $base_dir" >&2
|
|
200
|
+
return 1
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
return 0
|
|
204
|
+
}
|