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
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Cache Validator
|
|
3
|
+
*
|
|
4
|
+
* Provides SHA256 hash-based validation for skill content integrity and cache invalidation.
|
|
5
|
+
* Ensures cached skills remain synchronized with database content hashes.
|
|
6
|
+
*
|
|
7
|
+
* @module skill-cache-validator
|
|
8
|
+
*/ import * as crypto from 'crypto';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import { createLogger } from '../lib/logging.js';
|
|
11
|
+
/**
|
|
12
|
+
* Skill Cache Validator
|
|
13
|
+
*
|
|
14
|
+
* Validates skill content integrity using SHA256 hashing.
|
|
15
|
+
* Supports both in-memory content and file-based validation.
|
|
16
|
+
*/ export class SkillCacheValidator {
|
|
17
|
+
logger;
|
|
18
|
+
hashAlgorithm = 'sha256';
|
|
19
|
+
dbService;
|
|
20
|
+
constructor(logger, dbService){
|
|
21
|
+
this.logger = logger ?? createLogger('skill-cache-validator');
|
|
22
|
+
this.dbService = dbService;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Compute SHA256 hash of skill content
|
|
26
|
+
*
|
|
27
|
+
* @param content - Skill content to hash
|
|
28
|
+
* @returns SHA256 hash as hex string
|
|
29
|
+
*/ computeHash(content) {
|
|
30
|
+
return crypto.createHash(this.hashAlgorithm).update(content, 'utf8').digest('hex');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compute SHA256 hash from file
|
|
34
|
+
*
|
|
35
|
+
* @param filePath - Path to skill file
|
|
36
|
+
* @returns SHA256 hash as hex string
|
|
37
|
+
*/ async computeFileHash(filePath) {
|
|
38
|
+
return new Promise((resolve, reject)=>{
|
|
39
|
+
const hash = crypto.createHash(this.hashAlgorithm);
|
|
40
|
+
const stream = fs.createReadStream(filePath);
|
|
41
|
+
stream.on('data', (chunk)=>hash.update(chunk));
|
|
42
|
+
stream.on('end', ()=>resolve(hash.digest('hex')));
|
|
43
|
+
stream.on('error', (err)=>reject(err));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validate skill content against expected hash
|
|
48
|
+
*
|
|
49
|
+
* @param content - Skill content to validate
|
|
50
|
+
* @param expectedHash - Expected SHA256 hash
|
|
51
|
+
* @returns Validation result
|
|
52
|
+
*/ validateContent(content, expectedHash) {
|
|
53
|
+
const actualHash = this.computeHash(content);
|
|
54
|
+
if (actualHash === expectedHash) {
|
|
55
|
+
return {
|
|
56
|
+
isValid: true,
|
|
57
|
+
expectedHash,
|
|
58
|
+
actualHash
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
this.logger.warn('Skill content hash mismatch', {
|
|
62
|
+
expectedHash,
|
|
63
|
+
actualHash
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
isValid: false,
|
|
67
|
+
expectedHash,
|
|
68
|
+
actualHash,
|
|
69
|
+
reason: 'Content hash mismatch - skill content has been modified'
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate skill file against expected hash
|
|
74
|
+
*
|
|
75
|
+
* @param filePath - Path to skill file
|
|
76
|
+
* @param expectedHash - Expected SHA256 hash
|
|
77
|
+
* @returns Validation result
|
|
78
|
+
*/ async validateFile(filePath, expectedHash) {
|
|
79
|
+
try {
|
|
80
|
+
const actualHash = await this.computeFileHash(filePath);
|
|
81
|
+
if (actualHash === expectedHash) {
|
|
82
|
+
return {
|
|
83
|
+
isValid: true,
|
|
84
|
+
expectedHash,
|
|
85
|
+
actualHash
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
this.logger.warn('Skill file hash mismatch', {
|
|
89
|
+
filePath,
|
|
90
|
+
expectedHash,
|
|
91
|
+
actualHash
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
isValid: false,
|
|
95
|
+
expectedHash,
|
|
96
|
+
actualHash,
|
|
97
|
+
reason: `File hash mismatch - skill file has been modified: ${filePath}`
|
|
98
|
+
};
|
|
99
|
+
} catch (error) {
|
|
100
|
+
this.logger.error('Failed to validate skill file', error, {
|
|
101
|
+
filePath
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
isValid: false,
|
|
105
|
+
expectedHash,
|
|
106
|
+
reason: `Failed to read skill file: ${error.message}`
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validate cached skill entry
|
|
112
|
+
*
|
|
113
|
+
* Checks both content hash and TTL expiration.
|
|
114
|
+
*
|
|
115
|
+
* @param cachedEntry - Cached skill entry to validate
|
|
116
|
+
* @param expectedHash - Expected SHA256 hash from database
|
|
117
|
+
* @returns Validation result
|
|
118
|
+
*/ validateCachedEntry(cachedEntry, expectedHash) {
|
|
119
|
+
const now = new Date();
|
|
120
|
+
// Check TTL expiration
|
|
121
|
+
if (now > cachedEntry.validUntil) {
|
|
122
|
+
return {
|
|
123
|
+
isValid: false,
|
|
124
|
+
expectedHash,
|
|
125
|
+
actualHash: cachedEntry.contentHash,
|
|
126
|
+
reason: 'Cache entry expired (TTL exceeded)'
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// Check content hash
|
|
130
|
+
const actualHash = this.computeHash(cachedEntry.content);
|
|
131
|
+
if (actualHash !== cachedEntry.contentHash) {
|
|
132
|
+
this.logger.error('Cached entry content hash mismatch (cache corruption)', undefined, {
|
|
133
|
+
skillId: cachedEntry.skillId,
|
|
134
|
+
cachedHash: cachedEntry.contentHash,
|
|
135
|
+
actualHash
|
|
136
|
+
});
|
|
137
|
+
return {
|
|
138
|
+
isValid: false,
|
|
139
|
+
expectedHash,
|
|
140
|
+
actualHash,
|
|
141
|
+
reason: 'Cache corruption detected - cached hash does not match content'
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Check against expected hash from database
|
|
145
|
+
if (cachedEntry.contentHash !== expectedHash) {
|
|
146
|
+
return {
|
|
147
|
+
isValid: false,
|
|
148
|
+
expectedHash,
|
|
149
|
+
actualHash: cachedEntry.contentHash,
|
|
150
|
+
reason: 'Database content hash updated - cache invalidated'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
isValid: true,
|
|
155
|
+
expectedHash,
|
|
156
|
+
actualHash: cachedEntry.contentHash
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Batch validate multiple skill contents
|
|
161
|
+
*
|
|
162
|
+
* @param skills - Array of skill metadata to validate
|
|
163
|
+
* @returns Map of skillId to validation result
|
|
164
|
+
*/ batchValidate(skills) {
|
|
165
|
+
const results = new Map();
|
|
166
|
+
const startTime = Date.now();
|
|
167
|
+
for (const skill of skills){
|
|
168
|
+
results.set(skill.skillId, this.validateContent(skill.content, skill.expectedHash));
|
|
169
|
+
}
|
|
170
|
+
const duration = Date.now() - startTime;
|
|
171
|
+
this.logger.debug('Batch validation completed', {
|
|
172
|
+
count: skills.length,
|
|
173
|
+
durationMs: duration,
|
|
174
|
+
avgMs: duration / skills.length
|
|
175
|
+
});
|
|
176
|
+
return results;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Generate cache key for skill
|
|
180
|
+
*
|
|
181
|
+
* @param skillId - Skill identifier
|
|
182
|
+
* @param version - Skill version
|
|
183
|
+
* @returns Cache key string
|
|
184
|
+
*/ generateCacheKey(skillId, version) {
|
|
185
|
+
return `skill:${skillId}:${version}`;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if cache entry should be invalidated based on file modification time
|
|
189
|
+
*
|
|
190
|
+
* @param filePath - Path to skill file
|
|
191
|
+
* @param cachedAt - When the entry was cached
|
|
192
|
+
* @returns True if file was modified after caching
|
|
193
|
+
*/ async shouldInvalidateByFileTime(filePath, cachedAt) {
|
|
194
|
+
try {
|
|
195
|
+
const stats = await fs.promises.stat(filePath);
|
|
196
|
+
return stats.mtime > cachedAt;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
this.logger.warn('Failed to check file modification time', {
|
|
199
|
+
filePath,
|
|
200
|
+
error: error.message
|
|
201
|
+
});
|
|
202
|
+
// If we can't check the file, invalidate the cache to be safe
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Create cache entry with validation metadata
|
|
208
|
+
*
|
|
209
|
+
* @param skillId - Skill identifier
|
|
210
|
+
* @param content - Skill content
|
|
211
|
+
* @param ttlMinutes - Time-to-live in minutes (default: 5)
|
|
212
|
+
* @returns Cached skill entry
|
|
213
|
+
*/ createCacheEntry(skillId, content, ttlMinutes = 5) {
|
|
214
|
+
const now = new Date();
|
|
215
|
+
const validUntil = new Date(now.getTime() + ttlMinutes * 60 * 1000);
|
|
216
|
+
return {
|
|
217
|
+
skillId,
|
|
218
|
+
content,
|
|
219
|
+
contentHash: this.computeHash(content),
|
|
220
|
+
cachedAt: now,
|
|
221
|
+
validUntil
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Verify batch of hashes match their content
|
|
226
|
+
*
|
|
227
|
+
* Used for bulk cache warming and validation.
|
|
228
|
+
*
|
|
229
|
+
* @param entries - Array of cached entries to verify
|
|
230
|
+
* @returns Array of invalid skill IDs
|
|
231
|
+
*/ verifyBatchIntegrity(entries) {
|
|
232
|
+
const invalidSkills = [];
|
|
233
|
+
const startTime = Date.now();
|
|
234
|
+
for (const entry of entries){
|
|
235
|
+
const actualHash = this.computeHash(entry.content);
|
|
236
|
+
if (actualHash !== entry.contentHash) {
|
|
237
|
+
invalidSkills.push(entry.skillId);
|
|
238
|
+
this.logger.error('Cache integrity check failed', undefined, {
|
|
239
|
+
skillId: entry.skillId,
|
|
240
|
+
expectedHash: entry.contentHash,
|
|
241
|
+
actualHash
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const duration = Date.now() - startTime;
|
|
246
|
+
if (invalidSkills.length > 0) {
|
|
247
|
+
this.logger.warn('Cache integrity check found corrupted entries', {
|
|
248
|
+
totalChecked: entries.length,
|
|
249
|
+
corruptedCount: invalidSkills.length,
|
|
250
|
+
corruptedSkills: invalidSkills,
|
|
251
|
+
durationMs: duration
|
|
252
|
+
});
|
|
253
|
+
} else {
|
|
254
|
+
this.logger.debug('Cache integrity check passed', {
|
|
255
|
+
entriesChecked: entries.length,
|
|
256
|
+
durationMs: duration
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return invalidSkills;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Query skill content hashes from database in bulk
|
|
263
|
+
*
|
|
264
|
+
* Optimized single query with WHERE IN clause for performance.
|
|
265
|
+
* Performance target: <100ms for 100 skills
|
|
266
|
+
*
|
|
267
|
+
* @param skillIds - Array of skill IDs to query
|
|
268
|
+
* @returns Map of skill ID to content hash
|
|
269
|
+
*/ async querySkillHashes(skillIds) {
|
|
270
|
+
if (!this.dbService) {
|
|
271
|
+
this.logger.warn('Database service not configured - cannot query skill hashes');
|
|
272
|
+
return new Map();
|
|
273
|
+
}
|
|
274
|
+
if (skillIds.length === 0) {
|
|
275
|
+
return new Map();
|
|
276
|
+
}
|
|
277
|
+
const startTime = Date.now();
|
|
278
|
+
const hashes = new Map();
|
|
279
|
+
try {
|
|
280
|
+
// Get SQLite adapter
|
|
281
|
+
const sqlite = this.dbService.getAdapter('sqlite');
|
|
282
|
+
// Build bulk query with WHERE IN clause
|
|
283
|
+
const placeholders = skillIds.map(()=>'?').join(',');
|
|
284
|
+
const sql = `
|
|
285
|
+
SELECT id, content_hash
|
|
286
|
+
FROM skills
|
|
287
|
+
WHERE id IN (${placeholders})
|
|
288
|
+
`;
|
|
289
|
+
// Execute query
|
|
290
|
+
const records = await sqlite.raw(sql, skillIds);
|
|
291
|
+
// Build hash map
|
|
292
|
+
for (const record of records){
|
|
293
|
+
hashes.set(record.id, record.content_hash);
|
|
294
|
+
}
|
|
295
|
+
const duration = Date.now() - startTime;
|
|
296
|
+
this.logger.debug('Bulk hash query completed', {
|
|
297
|
+
skillCount: skillIds.length,
|
|
298
|
+
foundCount: hashes.size,
|
|
299
|
+
durationMs: duration,
|
|
300
|
+
avgMs: duration / skillIds.length
|
|
301
|
+
});
|
|
302
|
+
// Log performance warning if exceeding target
|
|
303
|
+
if (duration > 100) {
|
|
304
|
+
this.logger.warn('Bulk hash query exceeded 100ms target', {
|
|
305
|
+
durationMs: duration,
|
|
306
|
+
skillCount: skillIds.length,
|
|
307
|
+
target: 100
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return hashes;
|
|
311
|
+
} catch (error) {
|
|
312
|
+
this.logger.error('Failed to query skill hashes', error, {
|
|
313
|
+
skillIds
|
|
314
|
+
});
|
|
315
|
+
return new Map();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Validate cached skills against database hashes in bulk
|
|
320
|
+
*
|
|
321
|
+
* Optimized for performance with single database query.
|
|
322
|
+
* Performance target: <100ms for 100 skills
|
|
323
|
+
*
|
|
324
|
+
* @param cachedSkills - Array of cached skills to validate
|
|
325
|
+
* @returns Bulk validation result with invalid skill IDs
|
|
326
|
+
*/ async validateCachedSkills(cachedSkills) {
|
|
327
|
+
const startTime = Date.now();
|
|
328
|
+
if (cachedSkills.length === 0) {
|
|
329
|
+
return {
|
|
330
|
+
isValid: true,
|
|
331
|
+
invalidSkillIds: [],
|
|
332
|
+
validCount: 0,
|
|
333
|
+
invalidCount: 0,
|
|
334
|
+
durationMs: 0
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// Extract skill IDs
|
|
338
|
+
const skillIds = cachedSkills.map((skill)=>skill.skillId);
|
|
339
|
+
// Bulk query current hashes from database (single query)
|
|
340
|
+
const currentHashes = await this.querySkillHashes(skillIds);
|
|
341
|
+
// Compare cached vs current hashes in parallel
|
|
342
|
+
const invalidSkillIds = [];
|
|
343
|
+
const comparisons = cachedSkills.map((skill)=>{
|
|
344
|
+
const currentHash = currentHashes.get(skill.skillId);
|
|
345
|
+
if (!currentHash) {
|
|
346
|
+
// Skill not found in database - consider invalid
|
|
347
|
+
invalidSkillIds.push(skill.skillId);
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
if (currentHash !== skill.contentHash) {
|
|
351
|
+
// Hash mismatch - cache invalid
|
|
352
|
+
invalidSkillIds.push(skill.skillId);
|
|
353
|
+
this.logger.debug('Cache invalidated for skill', {
|
|
354
|
+
skillId: skill.skillId,
|
|
355
|
+
cachedHash: skill.contentHash,
|
|
356
|
+
currentHash
|
|
357
|
+
});
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
return true;
|
|
361
|
+
});
|
|
362
|
+
const validCount = comparisons.filter((match)=>match === true).length;
|
|
363
|
+
const invalidCount = invalidSkillIds.length;
|
|
364
|
+
const isValid = invalidCount === 0;
|
|
365
|
+
const durationMs = Date.now() - startTime;
|
|
366
|
+
this.logger.debug('Bulk cache validation completed', {
|
|
367
|
+
totalSkills: cachedSkills.length,
|
|
368
|
+
validCount,
|
|
369
|
+
invalidCount,
|
|
370
|
+
durationMs,
|
|
371
|
+
avgMs: durationMs / cachedSkills.length
|
|
372
|
+
});
|
|
373
|
+
// Log performance warning if exceeding target
|
|
374
|
+
if (durationMs > 100 && cachedSkills.length <= 100) {
|
|
375
|
+
this.logger.warn('Bulk cache validation exceeded 100ms target', {
|
|
376
|
+
durationMs,
|
|
377
|
+
skillCount: cachedSkills.length,
|
|
378
|
+
target: 100
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
isValid,
|
|
383
|
+
invalidSkillIds,
|
|
384
|
+
validCount,
|
|
385
|
+
invalidCount,
|
|
386
|
+
durationMs
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Singleton instance for global use
|
|
392
|
+
*/ let globalValidator = null;
|
|
393
|
+
/**
|
|
394
|
+
* Get or create global validator instance
|
|
395
|
+
*
|
|
396
|
+
* @param logger - Optional logger instance
|
|
397
|
+
* @returns Global validator instance
|
|
398
|
+
*/ export function getGlobalValidator(logger) {
|
|
399
|
+
if (!globalValidator) {
|
|
400
|
+
globalValidator = new SkillCacheValidator(logger);
|
|
401
|
+
}
|
|
402
|
+
return globalValidator;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Set global validator instance
|
|
406
|
+
*
|
|
407
|
+
* @param validator - Validator instance to use globally
|
|
408
|
+
*/ export function setGlobalValidator(validator) {
|
|
409
|
+
globalValidator = validator;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
//# sourceMappingURL=skill-cache-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/skill-cache-validator.ts"],"sourcesContent":["/**\r\n * Skill Cache Validator\r\n *\r\n * Provides SHA256 hash-based validation for skill content integrity and cache invalidation.\r\n * Ensures cached skills remain synchronized with database content hashes.\r\n *\r\n * @module skill-cache-validator\r\n */\r\n\r\nimport * as crypto from 'crypto';\r\nimport * as fs from 'fs';\r\nimport { createLogger, Logger } from '../lib/logging.js';\r\nimport { DatabaseService } from '../lib/database-service.js';\r\n\r\n/**\r\n * Cache validation result\r\n */\r\nexport interface ValidationResult {\r\n isValid: boolean;\r\n expectedHash: string;\r\n actualHash?: string;\r\n reason?: string;\r\n}\r\n\r\n/**\r\n * Skill content metadata for validation\r\n */\r\nexport interface SkillContentMetadata {\r\n skillId: string;\r\n content: string;\r\n filePath?: string;\r\n lastModified?: Date;\r\n}\r\n\r\n/**\r\n * Cache entry with validation metadata\r\n */\r\nexport interface CachedSkillEntry {\r\n skillId: string;\r\n content: string;\r\n contentHash: string;\r\n cachedAt: Date;\r\n validUntil: Date;\r\n}\r\n\r\n/**\r\n * Skill Cache Validator\r\n *\r\n * Validates skill content integrity using SHA256 hashing.\r\n * Supports both in-memory content and file-based validation.\r\n */\r\nexport class SkillCacheValidator {\r\n private logger: Logger;\r\n private hashAlgorithm: string = 'sha256';\r\n private dbService?: DatabaseService;\r\n\r\n constructor(logger?: Logger, dbService?: DatabaseService) {\r\n this.logger = logger ?? createLogger('skill-cache-validator');\r\n this.dbService = dbService;\r\n }\r\n\r\n /**\r\n * Compute SHA256 hash of skill content\r\n *\r\n * @param content - Skill content to hash\r\n * @returns SHA256 hash as hex string\r\n */\r\n computeHash(content: string): string {\r\n return crypto\r\n .createHash(this.hashAlgorithm)\r\n .update(content, 'utf8')\r\n .digest('hex');\r\n }\r\n\r\n /**\r\n * Compute SHA256 hash from file\r\n *\r\n * @param filePath - Path to skill file\r\n * @returns SHA256 hash as hex string\r\n */\r\n async computeFileHash(filePath: string): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const hash = crypto.createHash(this.hashAlgorithm);\r\n const stream = fs.createReadStream(filePath);\r\n\r\n stream.on('data', (chunk) => hash.update(chunk));\r\n stream.on('end', () => resolve(hash.digest('hex')));\r\n stream.on('error', (err) => reject(err));\r\n });\r\n }\r\n\r\n /**\r\n * Validate skill content against expected hash\r\n *\r\n * @param content - Skill content to validate\r\n * @param expectedHash - Expected SHA256 hash\r\n * @returns Validation result\r\n */\r\n validateContent(content: string, expectedHash: string): ValidationResult {\r\n const actualHash = this.computeHash(content);\r\n\r\n if (actualHash === expectedHash) {\r\n return {\r\n isValid: true,\r\n expectedHash,\r\n actualHash,\r\n };\r\n }\r\n\r\n this.logger.warn('Skill content hash mismatch', {\r\n expectedHash,\r\n actualHash,\r\n });\r\n\r\n return {\r\n isValid: false,\r\n expectedHash,\r\n actualHash,\r\n reason: 'Content hash mismatch - skill content has been modified',\r\n };\r\n }\r\n\r\n /**\r\n * Validate skill file against expected hash\r\n *\r\n * @param filePath - Path to skill file\r\n * @param expectedHash - Expected SHA256 hash\r\n * @returns Validation result\r\n */\r\n async validateFile(filePath: string, expectedHash: string): Promise<ValidationResult> {\r\n try {\r\n const actualHash = await this.computeFileHash(filePath);\r\n\r\n if (actualHash === expectedHash) {\r\n return {\r\n isValid: true,\r\n expectedHash,\r\n actualHash,\r\n };\r\n }\r\n\r\n this.logger.warn('Skill file hash mismatch', {\r\n filePath,\r\n expectedHash,\r\n actualHash,\r\n });\r\n\r\n return {\r\n isValid: false,\r\n expectedHash,\r\n actualHash,\r\n reason: `File hash mismatch - skill file has been modified: ${filePath}`,\r\n };\r\n } catch (error) {\r\n this.logger.error('Failed to validate skill file', error as Error, { filePath });\r\n\r\n return {\r\n isValid: false,\r\n expectedHash,\r\n reason: `Failed to read skill file: ${(error as Error).message}`,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Validate cached skill entry\r\n *\r\n * Checks both content hash and TTL expiration.\r\n *\r\n * @param cachedEntry - Cached skill entry to validate\r\n * @param expectedHash - Expected SHA256 hash from database\r\n * @returns Validation result\r\n */\r\n validateCachedEntry(\r\n cachedEntry: CachedSkillEntry,\r\n expectedHash: string\r\n ): ValidationResult {\r\n const now = new Date();\r\n\r\n // Check TTL expiration\r\n if (now > cachedEntry.validUntil) {\r\n return {\r\n isValid: false,\r\n expectedHash,\r\n actualHash: cachedEntry.contentHash,\r\n reason: 'Cache entry expired (TTL exceeded)',\r\n };\r\n }\r\n\r\n // Check content hash\r\n const actualHash = this.computeHash(cachedEntry.content);\r\n\r\n if (actualHash !== cachedEntry.contentHash) {\r\n this.logger.error('Cached entry content hash mismatch (cache corruption)', undefined, {\r\n skillId: cachedEntry.skillId,\r\n cachedHash: cachedEntry.contentHash,\r\n actualHash,\r\n });\r\n\r\n return {\r\n isValid: false,\r\n expectedHash,\r\n actualHash,\r\n reason: 'Cache corruption detected - cached hash does not match content',\r\n };\r\n }\r\n\r\n // Check against expected hash from database\r\n if (cachedEntry.contentHash !== expectedHash) {\r\n return {\r\n isValid: false,\r\n expectedHash,\r\n actualHash: cachedEntry.contentHash,\r\n reason: 'Database content hash updated - cache invalidated',\r\n };\r\n }\r\n\r\n return {\r\n isValid: true,\r\n expectedHash,\r\n actualHash: cachedEntry.contentHash,\r\n };\r\n }\r\n\r\n /**\r\n * Batch validate multiple skill contents\r\n *\r\n * @param skills - Array of skill metadata to validate\r\n * @returns Map of skillId to validation result\r\n */\r\n batchValidate(\r\n skills: Array<{ skillId: string; content: string; expectedHash: string }>\r\n ): Map<string, ValidationResult> {\r\n const results = new Map<string, ValidationResult>();\r\n const startTime = Date.now();\r\n\r\n for (const skill of skills) {\r\n results.set(\r\n skill.skillId,\r\n this.validateContent(skill.content, skill.expectedHash)\r\n );\r\n }\r\n\r\n const duration = Date.now() - startTime;\r\n this.logger.debug('Batch validation completed', {\r\n count: skills.length,\r\n durationMs: duration,\r\n avgMs: duration / skills.length,\r\n });\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Generate cache key for skill\r\n *\r\n * @param skillId - Skill identifier\r\n * @param version - Skill version\r\n * @returns Cache key string\r\n */\r\n generateCacheKey(skillId: string, version: string): string {\r\n return `skill:${skillId}:${version}`;\r\n }\r\n\r\n /**\r\n * Check if cache entry should be invalidated based on file modification time\r\n *\r\n * @param filePath - Path to skill file\r\n * @param cachedAt - When the entry was cached\r\n * @returns True if file was modified after caching\r\n */\r\n async shouldInvalidateByFileTime(\r\n filePath: string,\r\n cachedAt: Date\r\n ): Promise<boolean> {\r\n try {\r\n const stats = await fs.promises.stat(filePath);\r\n return stats.mtime > cachedAt;\r\n } catch (error) {\r\n this.logger.warn('Failed to check file modification time', {\r\n filePath,\r\n error: (error as Error).message,\r\n });\r\n // If we can't check the file, invalidate the cache to be safe\r\n return true;\r\n }\r\n }\r\n\r\n /**\r\n * Create cache entry with validation metadata\r\n *\r\n * @param skillId - Skill identifier\r\n * @param content - Skill content\r\n * @param ttlMinutes - Time-to-live in minutes (default: 5)\r\n * @returns Cached skill entry\r\n */\r\n createCacheEntry(\r\n skillId: string,\r\n content: string,\r\n ttlMinutes: number = 5\r\n ): CachedSkillEntry {\r\n const now = new Date();\r\n const validUntil = new Date(now.getTime() + ttlMinutes * 60 * 1000);\r\n\r\n return {\r\n skillId,\r\n content,\r\n contentHash: this.computeHash(content),\r\n cachedAt: now,\r\n validUntil,\r\n };\r\n }\r\n\r\n /**\r\n * Verify batch of hashes match their content\r\n *\r\n * Used for bulk cache warming and validation.\r\n *\r\n * @param entries - Array of cached entries to verify\r\n * @returns Array of invalid skill IDs\r\n */\r\n verifyBatchIntegrity(entries: CachedSkillEntry[]): string[] {\r\n const invalidSkills: string[] = [];\r\n const startTime = Date.now();\r\n\r\n for (const entry of entries) {\r\n const actualHash = this.computeHash(entry.content);\r\n\r\n if (actualHash !== entry.contentHash) {\r\n invalidSkills.push(entry.skillId);\r\n this.logger.error('Cache integrity check failed', undefined, {\r\n skillId: entry.skillId,\r\n expectedHash: entry.contentHash,\r\n actualHash,\r\n });\r\n }\r\n }\r\n\r\n const duration = Date.now() - startTime;\r\n\r\n if (invalidSkills.length > 0) {\r\n this.logger.warn('Cache integrity check found corrupted entries', {\r\n totalChecked: entries.length,\r\n corruptedCount: invalidSkills.length,\r\n corruptedSkills: invalidSkills,\r\n durationMs: duration,\r\n });\r\n } else {\r\n this.logger.debug('Cache integrity check passed', {\r\n entriesChecked: entries.length,\r\n durationMs: duration,\r\n });\r\n }\r\n\r\n return invalidSkills;\r\n }\r\n\r\n /**\r\n * Query skill content hashes from database in bulk\r\n *\r\n * Optimized single query with WHERE IN clause for performance.\r\n * Performance target: <100ms for 100 skills\r\n *\r\n * @param skillIds - Array of skill IDs to query\r\n * @returns Map of skill ID to content hash\r\n */\r\n async querySkillHashes(skillIds: string[]): Promise<Map<string, string>> {\r\n if (!this.dbService) {\r\n this.logger.warn('Database service not configured - cannot query skill hashes');\r\n return new Map();\r\n }\r\n\r\n if (skillIds.length === 0) {\r\n return new Map();\r\n }\r\n\r\n const startTime = Date.now();\r\n const hashes = new Map<string, string>();\r\n\r\n try {\r\n // Get SQLite adapter\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n // Build bulk query with WHERE IN clause\r\n const placeholders = skillIds.map(() => '?').join(',');\r\n const sql = `\r\n SELECT id, content_hash\r\n FROM skills\r\n WHERE id IN (${placeholders})\r\n `;\r\n\r\n // Execute query\r\n const records = await sqlite.raw<Array<{ id: string; content_hash: string }>>(\r\n sql,\r\n skillIds\r\n );\r\n\r\n // Build hash map\r\n for (const record of records) {\r\n hashes.set(record.id, record.content_hash);\r\n }\r\n\r\n const duration = Date.now() - startTime;\r\n\r\n this.logger.debug('Bulk hash query completed', {\r\n skillCount: skillIds.length,\r\n foundCount: hashes.size,\r\n durationMs: duration,\r\n avgMs: duration / skillIds.length,\r\n });\r\n\r\n // Log performance warning if exceeding target\r\n if (duration > 100) {\r\n this.logger.warn('Bulk hash query exceeded 100ms target', {\r\n durationMs: duration,\r\n skillCount: skillIds.length,\r\n target: 100,\r\n });\r\n }\r\n\r\n return hashes;\r\n } catch (error) {\r\n this.logger.error('Failed to query skill hashes', error as Error, {\r\n skillIds,\r\n });\r\n\r\n return new Map();\r\n }\r\n }\r\n\r\n /**\r\n * Validate cached skills against database hashes in bulk\r\n *\r\n * Optimized for performance with single database query.\r\n * Performance target: <100ms for 100 skills\r\n *\r\n * @param cachedSkills - Array of cached skills to validate\r\n * @returns Bulk validation result with invalid skill IDs\r\n */\r\n async validateCachedSkills(\r\n cachedSkills: CachedSkillEntry[]\r\n ): Promise<{\r\n isValid: boolean;\r\n invalidSkillIds: string[];\r\n validCount: number;\r\n invalidCount: number;\r\n durationMs: number;\r\n }> {\r\n const startTime = Date.now();\r\n\r\n if (cachedSkills.length === 0) {\r\n return {\r\n isValid: true,\r\n invalidSkillIds: [],\r\n validCount: 0,\r\n invalidCount: 0,\r\n durationMs: 0,\r\n };\r\n }\r\n\r\n // Extract skill IDs\r\n const skillIds = cachedSkills.map((skill) => skill.skillId);\r\n\r\n // Bulk query current hashes from database (single query)\r\n const currentHashes = await this.querySkillHashes(skillIds);\r\n\r\n // Compare cached vs current hashes in parallel\r\n const invalidSkillIds: string[] = [];\r\n const comparisons = cachedSkills.map((skill) => {\r\n const currentHash = currentHashes.get(skill.skillId);\r\n\r\n if (!currentHash) {\r\n // Skill not found in database - consider invalid\r\n invalidSkillIds.push(skill.skillId);\r\n return false;\r\n }\r\n\r\n if (currentHash !== skill.contentHash) {\r\n // Hash mismatch - cache invalid\r\n invalidSkillIds.push(skill.skillId);\r\n this.logger.debug('Cache invalidated for skill', {\r\n skillId: skill.skillId,\r\n cachedHash: skill.contentHash,\r\n currentHash,\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n\r\n const validCount = comparisons.filter((match) => match === true).length;\r\n const invalidCount = invalidSkillIds.length;\r\n const isValid = invalidCount === 0;\r\n const durationMs = Date.now() - startTime;\r\n\r\n this.logger.debug('Bulk cache validation completed', {\r\n totalSkills: cachedSkills.length,\r\n validCount,\r\n invalidCount,\r\n durationMs,\r\n avgMs: durationMs / cachedSkills.length,\r\n });\r\n\r\n // Log performance warning if exceeding target\r\n if (durationMs > 100 && cachedSkills.length <= 100) {\r\n this.logger.warn('Bulk cache validation exceeded 100ms target', {\r\n durationMs,\r\n skillCount: cachedSkills.length,\r\n target: 100,\r\n });\r\n }\r\n\r\n return {\r\n isValid,\r\n invalidSkillIds,\r\n validCount,\r\n invalidCount,\r\n durationMs,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Singleton instance for global use\r\n */\r\nlet globalValidator: SkillCacheValidator | null = null;\r\n\r\n/**\r\n * Get or create global validator instance\r\n *\r\n * @param logger - Optional logger instance\r\n * @returns Global validator instance\r\n */\r\nexport function getGlobalValidator(logger?: Logger): SkillCacheValidator {\r\n if (!globalValidator) {\r\n globalValidator = new SkillCacheValidator(logger);\r\n }\r\n return globalValidator;\r\n}\r\n\r\n/**\r\n * Set global validator instance\r\n *\r\n * @param validator - Validator instance to use globally\r\n */\r\nexport function setGlobalValidator(validator: SkillCacheValidator): void {\r\n globalValidator = validator;\r\n}\r\n"],"names":["crypto","fs","createLogger","SkillCacheValidator","logger","hashAlgorithm","dbService","computeHash","content","createHash","update","digest","computeFileHash","filePath","Promise","resolve","reject","hash","stream","createReadStream","on","chunk","err","validateContent","expectedHash","actualHash","isValid","warn","reason","validateFile","error","message","validateCachedEntry","cachedEntry","now","Date","validUntil","contentHash","undefined","skillId","cachedHash","batchValidate","skills","results","Map","startTime","skill","set","duration","debug","count","length","durationMs","avgMs","generateCacheKey","version","shouldInvalidateByFileTime","cachedAt","stats","promises","stat","mtime","createCacheEntry","ttlMinutes","getTime","verifyBatchIntegrity","entries","invalidSkills","entry","push","totalChecked","corruptedCount","corruptedSkills","entriesChecked","querySkillHashes","skillIds","hashes","sqlite","getAdapter","placeholders","map","join","sql","records","raw","record","id","content_hash","skillCount","foundCount","size","target","validateCachedSkills","cachedSkills","invalidSkillIds","validCount","invalidCount","currentHashes","comparisons","currentHash","get","filter","match","totalSkills","globalValidator","getGlobalValidator","setGlobalValidator","validator"],"mappings":"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"}
|