claude-flow-novice 2.15.11 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/cfn-extras/agents/cfn-v3-coordinator.md +517 -0
- package/.claude/commands/cfn-loop-cli.md +158 -464
- package/.claude/commands/cfn-loop-trigger.md +114 -0
- package/.claude/hooks/cfn-invoke-post-edit-ts.sh +100 -0
- package/.claude/hooks/cfn-invoke-post-edit-ts.sh.backup +78 -0
- package/.claude/hooks/cfn-invoke-post-edit.sh +22 -0
- package/.claude/hooks/cfn-invoke-post-edit.sh.backup +87 -0
- package/.claude/hooks/cfn-invoke-pre-edit-ts.sh +116 -0
- package/.claude/hooks/cfn-invoke-pre-edit-ts.sh.backup +94 -0
- package/.claude/hooks/cfn-invoke-pre-edit.sh +22 -0
- package/.claude/hooks/cfn-invoke-pre-edit.sh.backup +88 -0
- package/.claude/skills/cfn-agent-spawning/SKILL.md +48 -1
- package/.claude/skills/cfn-agent-spawning/SKILL.md.backup +135 -0
- package/.claude/skills/cfn-agent-spawning/TYPESCRIPT_MIGRATION.md +567 -0
- package/.claude/skills/cfn-agent-spawning/check-dependencies.sh +22 -0
- package/.claude/skills/{cfn-redis-coordination/check-dependencies.sh → cfn-agent-spawning/check-dependencies.sh.backup} +3 -5
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh.backup +127 -0
- package/.claude/skills/cfn-agent-spawning/parse-agent-provider.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/parse-agent-provider.sh.backup +59 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent-wrapper.sh +63 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent-wrapper.sh.backup +41 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +26 -1
- package/.claude/skills/cfn-agent-spawning/spawn-templates.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/spawn-templates.sh.backup +613 -0
- package/.claude/skills/cfn-agent-spawning/spawn-worker.sh +22 -0
- package/.claude/skills/cfn-agent-spawning/spawn-worker.sh.backup +176 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/metadata.json +8 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/original +271 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/revert.sh +7 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/metadata.json +8 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/original +325 -0
- package/.claude/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/revert.sh +7 -0
- package/.claude/skills/cfn-loop-orchestration/CLI_IMPLEMENTATION_SUMMARY.md +330 -0
- package/.claude/skills/cfn-loop-orchestration/CONFIGURATION_IMPROVEMENTS.md +318 -0
- package/.claude/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_MIGRATION.md +308 -0
- package/.claude/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_QUICK_START.md +378 -0
- package/.claude/skills/cfn-loop-orchestration/E2E_VALIDATION_REPORT.md +262 -0
- package/.claude/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +319 -519
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_E2E_REPORT.md +299 -0
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_EXECUTION_SUMMARY.md +403 -0
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +323 -0
- package/.claude/skills/cfn-loop-orchestration/SKILL.md +159 -48
- package/.claude/skills/cfn-loop-orchestration/SPAWN_AGENTS_IMPLEMENTATION.md +188 -0
- package/.claude/skills/cfn-loop-orchestration/TEST_COVERAGE_REPORT.md +335 -0
- package/.claude/skills/cfn-loop-orchestration/TEST_COVERAGE_SUMMARY.md +456 -0
- package/.claude/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_REPORT.md +709 -0
- package/.claude/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_SUMMARY.md +257 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATION_REPORT.md +572 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATION_SUMMARY.txt +196 -0
- package/.claude/skills/cfn-loop-orchestration/VALIDATOR_MODULE_GUIDE.md +526 -0
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/README.md +167 -0
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate-enhanced.sh +548 -0
- package/{claude-assets/skills/cfn-loop-orchestration → .claude/skills/cfn-loop-orchestration/archive/legacy-bash}/orchestrate-wrapper.sh +11 -1
- package/.claude/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate.sh +182 -0
- package/.claude/skills/cfn-loop-orchestration/e2e-validation-fixed.js +240 -0
- package/.claude/skills/cfn-loop-orchestration/e2e-validation.js +213 -0
- package/.claude/skills/cfn-loop-orchestration/package-lock.json +3 -0
- package/.claude/skills/cfn-loop-orchestration/package.json +4 -0
- package/.claude/skills/cfn-loop-orchestration/run-north-star-e2e.ts +210 -0
- package/.claude/skills/cfn-loop-orchestration/src/cli/orchestrator-cli.ts +396 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR.md +564 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR_QUICK_REF.md +241 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_IMPLEMENTATION.md +375 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_QUICK_REFERENCE.md +362 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_README.md +307 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_USAGE_GUIDE.md +508 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts +473 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/consensus.ts +1 -1
- package/.claude/skills/cfn-loop-orchestration/src/helpers/context-injector.ts +349 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/context-lookup.ts +486 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/deliverable-verifier.ts +6 -2
- package/.claude/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +1 -1
- package/.claude/skills/cfn-loop-orchestration/src/helpers/product-owner-decision.ts +316 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/spawn-agents.ts +357 -0
- package/.claude/skills/cfn-loop-orchestration/src/helpers/validator.ts +276 -0
- package/.claude/skills/cfn-loop-orchestration/src/index.ts +2 -0
- package/.claude/skills/cfn-loop-orchestration/src/orchestrate.ts +743 -2
- package/.claude/skills/cfn-loop-orchestration/src/types.ts +56 -0
- package/.claude/skills/cfn-loop-orchestration/test-cli.sh +92 -0
- package/.claude/skills/cfn-loop-orchestration/test-typescript-integration.sh +442 -0
- package/.claude/skills/cfn-loop-orchestration/tests/agent-spawner.test.ts +124 -0
- package/.claude/skills/cfn-loop-orchestration/tests/confidence-aggregator.test.ts +604 -0
- package/.claude/skills/cfn-loop-orchestration/tests/context-injector.test.ts +561 -0
- package/.claude/skills/cfn-loop-orchestration/tests/context-lookup.test.ts +661 -0
- package/.claude/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +2 -2
- package/.claude/skills/cfn-loop-orchestration/tests/gate-check-edge-cases.test.ts +422 -0
- package/.claude/skills/cfn-loop-orchestration/tests/gate-checker.test.ts +276 -0
- package/.claude/skills/cfn-loop-orchestration/tests/logger.test.ts +291 -0
- package/.claude/skills/cfn-loop-orchestration/tests/north-star-e2e.test.ts +334 -0
- package/.claude/skills/cfn-loop-orchestration/tests/redis-coordinator.test.ts +321 -0
- package/.claude/skills/cfn-loop-orchestration/tests/spawn-agents.test.ts +284 -0
- package/.claude/skills/cfn-loop-orchestration/tests/validator.test.ts +643 -0
- package/.claude/skills/cfn-loop-validation/IMPLEMENTATION_SUMMARY.md +672 -0
- package/.claude/skills/cfn-loop-validation/INDEX.md +531 -0
- package/.claude/skills/cfn-loop-validation/README_TYPESCRIPT.md +454 -0
- package/.claude/skills/cfn-loop-validation/SKILL.md +48 -1
- package/.claude/skills/cfn-loop-validation/SKILL.md.backup +353 -0
- package/.claude/skills/cfn-loop-validation/SKILL_TYPESCRIPT.md +782 -0
- package/.claude/skills/cfn-loop-validation/VAPOR_DETECTION_EXAMPLES.md +598 -0
- package/.claude/skills/cfn-loop-validation/check-dependencies.sh +22 -0
- package/{claude-assets/skills/cfn-redis-coordination/check-dependencies.sh → .claude/skills/cfn-loop-validation/check-dependencies.sh.backup} +4 -5
- package/.claude/skills/cfn-loop-validation/detect-vapor.sh +59 -0
- package/.claude/skills/cfn-loop-validation/detect-vapor.sh.backup +37 -0
- package/.claude/skills/cfn-loop-validation/dist/.tsbuildinfo +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts +14 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.js +185 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/detect-vapor.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts +14 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.js +176 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-deliverables.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts +19 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.js +123 -0
- package/.claude/skills/cfn-loop-validation/dist/cli/validate-gate.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/types.d.ts +156 -0
- package/.claude/skills/cfn-loop-validation/dist/types.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/types.js +66 -0
- package/.claude/skills/cfn-loop-validation/dist/types.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.d.ts +85 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.d.ts.map +1 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.js +411 -0
- package/.claude/skills/cfn-loop-validation/dist/validator.js.map +1 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +22 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh.backup +252 -0
- package/.claude/skills/cfn-loop-validation/package.json +93 -0
- package/.claude/skills/cfn-loop-validation/src/cli/detect-vapor.ts +177 -0
- package/.claude/skills/cfn-loop-validation/src/cli/validate-deliverables.ts +161 -0
- package/.claude/skills/cfn-loop-validation/src/cli/validate-gate.ts +139 -0
- package/.claude/skills/cfn-loop-validation/src/types.ts +215 -0
- package/.claude/skills/cfn-loop-validation/src/validator.ts +503 -0
- package/.claude/skills/cfn-loop-validation/tests/validator.test.ts +537 -0
- package/.claude/skills/{cfn-redis-coordination → cfn-loop-validation}/tsconfig.json +34 -31
- package/.claude/skills/cfn-loop-validation/validate-deliverables.sh +59 -0
- package/.claude/skills/cfn-loop-validation/validate-deliverables.sh.backup +37 -0
- package/.claude/skills/cfn-loop-validation/validate-gate.sh +63 -0
- package/.claude/skills/cfn-loop-validation/validate-gate.sh.backup +41 -0
- package/.claude/skills/cfn-loop-validation/validate-iteration.sh +22 -0
- package/.claude/skills/cfn-loop-validation/validate-iteration.sh.backup +134 -0
- package/.claude/skills/cfn-product-owner-decision/SKILL.md +479 -147
- package/.claude/skills/cfn-product-owner-decision/TYPESCRIPT_IMPLEMENTATION.md +653 -0
- package/{claude-assets/skills/cfn-product-owner-decision → .claude/skills/cfn-product-owner-decision/archive/legacy-bash}/execute-decision.sh +24 -2
- package/.claude/skills/pre-edit-backup/SKILL.md +324 -0
- package/.claude/skills/pre-edit-backup/SKILL.md.backup +277 -0
- package/.claude/skills/pre-edit-backup/backup.sh +22 -0
- package/.claude/skills/pre-edit-backup/backup.sh.backup +107 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +1 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +10 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +56 -33
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +46 -36
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +9 -0
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +17 -17
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +40 -58
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +18 -20
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +19 -28
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +15 -19
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +15 -10
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +15 -10
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +15 -25
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +17 -21
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +17 -21
- package/claude-assets/agents/cfn-dev-team/product-owners/product-owner.md +1 -5
- package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +20 -51
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +22 -71
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +21 -64
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +22 -67
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +23 -67
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +7 -35
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +8 -37
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +16 -54
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +17 -55
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +9 -37
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +17 -55
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +17 -48
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +8 -37
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +7 -27
- package/claude-assets/agents/cfn-dev-team/utility/analyst.md +12 -28
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +13 -13
- package/claude-assets/agents/cfn-dev-team/utility/context-curator.md +7 -2
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +5 -10
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +120 -714
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +12 -21
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +146 -572
- package/claude-assets/agents/custom/cfn-docker-expert.md +102 -0
- package/claude-assets/agents/custom/cfn-loops-cli-expert.md +129 -0
- package/claude-assets/cfn-extras/agents/cfn-v3-coordinator.md +517 -0
- package/claude-assets/commands/cfn-loop-cli.md +158 -464
- package/claude-assets/commands/cfn-loop-trigger.md +114 -0
- package/claude-assets/hooks/SKILL.md +518 -0
- package/claude-assets/hooks/SKILL.md.backup +471 -0
- package/claude-assets/hooks/cfn-invoke-post-edit-ts.sh +100 -0
- package/claude-assets/hooks/cfn-invoke-post-edit-ts.sh.backup +78 -0
- package/claude-assets/hooks/cfn-invoke-post-edit.sh +22 -0
- package/claude-assets/hooks/cfn-invoke-post-edit.sh.backup +87 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit-ts.sh +116 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit-ts.sh.backup +94 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit.sh +22 -0
- package/claude-assets/hooks/cfn-invoke-pre-edit.sh.backup +88 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/DELIVERABLES.md +409 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/IMPLEMENTATION_SUMMARY.md +396 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/INTEGRATION_GUIDE.md +308 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/QUICK_REFERENCE.md +239 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md +107 -1
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md.backup +302 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/TYPESCRIPT_MIGRATION.md +295 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/agent-selector.cjs +297 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/agent-selector.js +297 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/cli.cjs +96 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/dist/cli.js +96 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents-ts.sh +45 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents-ts.sh.backup +23 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh +22 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh.backup +173 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/agent-selector.test.ts +357 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/agent-selector.ts +350 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/src/cli.ts +74 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh +22 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh.backup +71 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/tsconfig.json +18 -0
- package/claude-assets/skills/cfn-agent-spawning/SKILL.md +48 -1
- package/claude-assets/skills/cfn-agent-spawning/SKILL.md.backup +135 -0
- package/claude-assets/skills/cfn-agent-spawning/TYPESCRIPT_MIGRATION.md +567 -0
- package/claude-assets/skills/cfn-agent-spawning/check-dependencies.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/check-dependencies.sh.backup +30 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh.backup +127 -0
- package/claude-assets/skills/cfn-agent-spawning/parse-agent-provider.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/parse-agent-provider.sh.backup +59 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent-wrapper.sh +63 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent-wrapper.sh.backup +41 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +26 -1
- package/claude-assets/skills/cfn-agent-spawning/spawn-templates.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-templates.sh.backup +613 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-worker.sh +22 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-worker.sh.backup +176 -0
- package/claude-assets/skills/cfn-coordination/agent-completion.sh.backup +36 -0
- package/claude-assets/skills/cfn-coordination/coordination-signal.sh.backup +36 -0
- package/claude-assets/skills/cfn-coordination/coordination-wait.sh.backup +36 -0
- package/claude-assets/skills/cfn-dependency-ingestion/README.md +101 -0
- package/claude-assets/skills/cfn-dependency-ingestion/SKILL.md +369 -0
- package/claude-assets/skills/cfn-dependency-ingestion/build.sh +23 -0
- package/claude-assets/skills/cfn-dependency-ingestion/dist/ingest-dependencies.js +478 -0
- package/claude-assets/skills/cfn-dependency-ingestion/ingest-dependencies.sh +295 -0
- package/claude-assets/skills/cfn-dependency-ingestion/src/ingest-dependencies.ts +563 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/metadata.json +8 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/original +271 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763619700_33aff4a69b99159e4e849107ebc4d09f/revert.sh +7 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/metadata.json +8 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/original +325 -0
- package/claude-assets/skills/cfn-loop-orchestration/.backups/unknown/1763671642_06496e8c399a79db08167cc00ed4b31e/revert.sh +7 -0
- package/claude-assets/skills/cfn-loop-orchestration/CLI_IMPLEMENTATION_SUMMARY.md +330 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONFIGURATION_IMPROVEMENTS.md +318 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_MIGRATION.md +308 -0
- package/claude-assets/skills/cfn-loop-orchestration/CONTEXT_LOOKUP_QUICK_START.md +378 -0
- package/claude-assets/skills/cfn-loop-orchestration/E2E_VALIDATION_REPORT.md +262 -0
- package/claude-assets/skills/cfn-loop-orchestration/IMPLEMENTATION_SUMMARY.md +319 -519
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_E2E_REPORT.md +299 -0
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_EXECUTION_SUMMARY.md +403 -0
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +323 -0
- package/claude-assets/skills/cfn-loop-orchestration/SKILL.md +159 -48
- package/claude-assets/skills/cfn-loop-orchestration/SPAWN_AGENTS_IMPLEMENTATION.md +188 -0
- package/claude-assets/skills/cfn-loop-orchestration/TEST_COVERAGE_REPORT.md +335 -0
- package/claude-assets/skills/cfn-loop-orchestration/TEST_COVERAGE_SUMMARY.md +456 -0
- package/claude-assets/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_REPORT.md +709 -0
- package/claude-assets/skills/cfn-loop-orchestration/TYPESCRIPT_INTEGRATION_SUMMARY.md +257 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATION_REPORT.md +572 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATION_SUMMARY.txt +196 -0
- package/claude-assets/skills/cfn-loop-orchestration/VALIDATOR_MODULE_GUIDE.md +526 -0
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/README.md +167 -0
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate-enhanced.sh +548 -0
- package/{.claude/skills/cfn-loop-orchestration → claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash}/orchestrate-wrapper.sh +11 -1
- package/claude-assets/skills/cfn-loop-orchestration/archive/legacy-bash/orchestrate.sh +182 -0
- package/claude-assets/skills/cfn-loop-orchestration/e2e-validation-fixed.js +240 -0
- package/claude-assets/skills/cfn-loop-orchestration/e2e-validation.js +213 -0
- package/claude-assets/skills/cfn-loop-orchestration/package-lock.json +3 -0
- package/claude-assets/skills/cfn-loop-orchestration/package.json +4 -0
- package/claude-assets/skills/cfn-loop-orchestration/run-north-star-e2e.ts +210 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/cli/orchestrator-cli.ts +396 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR.md +564 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONFIDENCE_AGGREGATOR_QUICK_REF.md +241 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_IMPLEMENTATION.md +375 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_QUICK_REFERENCE.md +362 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_README.md +307 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/CONTEXT_INJECTOR_USAGE_GUIDE.md +508 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/confidence-aggregator.ts +473 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/consensus.ts +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/context-injector.ts +349 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/context-lookup.ts +486 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/deliverable-verifier.ts +6 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +1 -1
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/product-owner-decision.ts +316 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/spawn-agents.ts +357 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/helpers/validator.ts +276 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/index.ts +2 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/orchestrate.ts +743 -2
- package/claude-assets/skills/cfn-loop-orchestration/src/types.ts +56 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-cli.sh +92 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-typescript-integration.sh +442 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/agent-spawner.test.ts +124 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/confidence-aggregator.test.ts +604 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/context-injector.test.ts +561 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/context-lookup.test.ts +661 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +2 -2
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-check-edge-cases.test.ts +422 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/gate-checker.test.ts +276 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/logger.test.ts +291 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/north-star-e2e.test.ts +334 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/redis-coordinator.test.ts +321 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/spawn-agents.test.ts +284 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/validator.test.ts +643 -0
- package/claude-assets/skills/cfn-loop-output-processing/.eslintrc.json +33 -0
- package/claude-assets/skills/cfn-loop-output-processing/DELIVERY_SUMMARY.txt +462 -0
- package/claude-assets/skills/cfn-loop-output-processing/DEPRECATION_NOTICE.md +183 -0
- package/claude-assets/skills/cfn-loop-output-processing/EXAMPLES.md +609 -0
- package/claude-assets/skills/cfn-loop-output-processing/IMPLEMENTATION_SUMMARY.md +418 -0
- package/claude-assets/skills/cfn-loop-output-processing/INDEX.md +531 -0
- package/claude-assets/skills/cfn-loop-output-processing/MIGRATION.md +362 -0
- package/claude-assets/skills/cfn-loop-output-processing/README.md +114 -0
- package/claude-assets/skills/cfn-loop-output-processing/SKILL.md +633 -0
- package/{.claude/skills/cfn-docker-redis-coordination → claude-assets/skills/cfn-loop-output-processing}/jest.config.js +7 -15
- package/claude-assets/skills/cfn-loop-output-processing/package.json +50 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/cli/process-loop2.ts +195 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/cli/process-loop3.ts +157 -0
- package/claude-assets/skills/cfn-loop-output-processing/src/output-processor.ts +632 -0
- package/claude-assets/skills/cfn-loop-output-processing/tests/output-processor.test.ts +617 -0
- package/claude-assets/skills/{cfn-docker-redis-coordination → cfn-loop-output-processing}/tsconfig.json +16 -7
- package/claude-assets/skills/cfn-loop-validation/IMPLEMENTATION_SUMMARY.md +672 -0
- package/claude-assets/skills/cfn-loop-validation/INDEX.md +531 -0
- package/claude-assets/skills/cfn-loop-validation/README_TYPESCRIPT.md +454 -0
- package/claude-assets/skills/cfn-loop-validation/SKILL.md +48 -1
- package/claude-assets/skills/cfn-loop-validation/SKILL.md.backup +353 -0
- package/claude-assets/skills/cfn-loop-validation/SKILL_TYPESCRIPT.md +782 -0
- package/claude-assets/skills/cfn-loop-validation/VAPOR_DETECTION_EXAMPLES.md +598 -0
- package/claude-assets/skills/cfn-loop-validation/check-dependencies.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/check-dependencies.sh.backup +31 -0
- package/claude-assets/skills/cfn-loop-validation/detect-vapor.sh +59 -0
- package/claude-assets/skills/cfn-loop-validation/detect-vapor.sh.backup +37 -0
- package/claude-assets/skills/cfn-loop-validation/dist/.tsbuildinfo +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts +14 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.js +185 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/detect-vapor.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts +14 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.js +176 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-deliverables.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts +19 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.js +123 -0
- package/claude-assets/skills/cfn-loop-validation/dist/cli/validate-gate.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.d.ts +156 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.js +66 -0
- package/claude-assets/skills/cfn-loop-validation/dist/types.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.d.ts +85 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.d.ts.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.js +411 -0
- package/claude-assets/skills/cfn-loop-validation/dist/validator.js.map +1 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh.backup +252 -0
- package/claude-assets/skills/cfn-loop-validation/package.json +93 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/detect-vapor.ts +177 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/validate-deliverables.ts +161 -0
- package/claude-assets/skills/cfn-loop-validation/src/cli/validate-gate.ts +139 -0
- package/claude-assets/skills/cfn-loop-validation/src/types.ts +215 -0
- package/claude-assets/skills/cfn-loop-validation/src/validator.ts +503 -0
- package/claude-assets/skills/cfn-loop-validation/tests/validator.test.ts +537 -0
- package/claude-assets/skills/{cfn-redis-coordination → cfn-loop-validation}/tsconfig.json +34 -31
- package/claude-assets/skills/cfn-loop-validation/validate-deliverables.sh +59 -0
- package/claude-assets/skills/cfn-loop-validation/validate-deliverables.sh.backup +37 -0
- package/claude-assets/skills/cfn-loop-validation/validate-gate.sh +63 -0
- package/claude-assets/skills/cfn-loop-validation/validate-gate.sh.backup +41 -0
- package/claude-assets/skills/cfn-loop-validation/validate-iteration.sh +22 -0
- package/claude-assets/skills/cfn-loop-validation/validate-iteration.sh.backup +134 -0
- package/claude-assets/skills/cfn-product-owner-decision/SKILL.md +479 -147
- package/claude-assets/skills/cfn-product-owner-decision/TYPESCRIPT_IMPLEMENTATION.md +653 -0
- package/{.claude/skills/cfn-product-owner-decision → claude-assets/skills/cfn-product-owner-decision/archive/legacy-bash}/execute-decision.sh +24 -2
- package/claude-assets/skills/cfn-provider-routing/README.md +129 -0
- package/claude-assets/skills/cfn-provider-routing/SKILL.md +192 -0
- package/claude-assets/skills/cfn-provider-routing/resolve-provider-model.ts +223 -0
- package/claude-assets/skills/pre-edit-backup/SKILL.md +324 -0
- package/claude-assets/skills/pre-edit-backup/SKILL.md.backup +277 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh +22 -0
- package/claude-assets/skills/pre-edit-backup/backup.sh.backup +107 -0
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/api/auth-endpoints.js +415 -0
- package/dist/api/auth-endpoints.js.map +1 -0
- package/dist/api/task-endpoints.js +562 -0
- package/dist/api/task-endpoints.js.map +1 -0
- package/dist/backend/server.js +418 -0
- package/dist/backend/server.js.map +1 -0
- package/dist/cfn-loop/product-owner/decision-parser.js +356 -0
- package/dist/cfn-loop/product-owner/decision-parser.js.map +1 -0
- package/dist/cfn-loop/product-owner/index.js +1 -0
- package/dist/cfn-loop/product-owner/index.js.map +1 -1
- package/dist/cli/agent-command.js +1 -1
- package/dist/cli/agent-command.js.map +1 -1
- package/dist/cli/agent-completion.js +273 -0
- package/dist/cli/agent-completion.js.map +1 -0
- package/dist/cli/agent-prompt-builder.js +83 -48
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawner.js +499 -0
- package/dist/cli/agent-spawner.js.map +1 -0
- package/dist/cli/anthropic-client.js +10 -3
- package/dist/cli/anthropic-client.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/parse-decision-cli.js +268 -0
- package/dist/cli/parse-decision-cli.js.map +1 -0
- package/dist/cli/post-edit-hook.js +83 -0
- package/dist/cli/post-edit-hook.js.map +1 -0
- package/dist/cli/pre-edit-hook.js +77 -0
- package/dist/cli/pre-edit-hook.js.map +1 -0
- package/dist/cli/spawn-agent-cli.js +209 -0
- package/dist/cli/spawn-agent-cli.js.map +1 -0
- package/dist/coordination/coordination-wrapper.js +383 -0
- package/dist/coordination/coordination-wrapper.js.map +1 -0
- package/dist/coordination/store-success-criteria.js +68 -0
- package/dist/coordination/store-success-criteria.js.map +1 -0
- package/dist/coordination/store-task-context.js +65 -0
- package/dist/coordination/store-task-context.js.map +1 -0
- package/dist/hooks/backup-manager.js +273 -0
- package/dist/hooks/backup-manager.js.map +1 -0
- package/dist/hooks/post-edit-validator.js +388 -0
- package/dist/hooks/post-edit-validator.js.map +1 -0
- package/dist/integration/index.js +19 -0
- package/dist/integration/index.js.map +1 -0
- package/dist/integration/task-mode-adapter.js +297 -0
- package/dist/integration/task-mode-adapter.js.map +1 -0
- package/dist/integration/trigger-dev-client.js +253 -0
- package/dist/integration/trigger-dev-client.js.map +1 -0
- package/dist/integration/trigger-dev-webhooks.js +362 -0
- package/dist/integration/trigger-dev-webhooks.js.map +1 -0
- package/dist/lib/path-validator.js +14 -5
- package/dist/lib/path-validator.js.map +1 -1
- package/dist/lib/redis-queue-manager.js +5 -1
- package/dist/lib/redis-queue-manager.js.map +1 -1
- package/dist/middleware/authentication.js +317 -0
- package/dist/middleware/authentication.js.map +1 -0
- package/dist/services/authentication.js +669 -0
- package/dist/services/authentication.js.map +1 -0
- package/dist/services/session-management.js +436 -0
- package/dist/services/session-management.js.map +1 -0
- package/dist/services/skill-deployment.js +8 -6
- package/dist/services/skill-deployment.js.map +1 -1
- package/dist/services/user-service.js +710 -0
- package/dist/services/user-service.js.map +1 -0
- package/dist/types/trigger-dev-events.d.js +10 -0
- package/dist/types/trigger-dev-events.d.js.map +1 -0
- package/docs/README.md +240 -0
- package/package.json +13 -4
- package/scripts/compare-workflow-performance.sh +556 -0
- package/scripts/migrate-to-optimized-workflows.sh +438 -0
- package/scripts/organize-docs.sh +338 -0
- package/scripts/trigger-dev-setup.sh +267 -0
- package/.claude/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +0 -348
- package/.claude/skills/cfn-docker-redis-coordination/README.md +0 -294
- package/.claude/skills/cfn-docker-redis-coordination/SKILL.md +0 -435
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh +0 -650
- package/.claude/skills/cfn-docker-redis-coordination/coordinate.sh.backup-1763145142 +0 -641
- package/.claude/skills/cfn-docker-redis-coordination/package-lock.json +0 -5259
- package/.claude/skills/cfn-docker-redis-coordination/package.json +0 -40
- package/.claude/skills/cfn-docker-redis-coordination/src/coordinator.ts +0 -801
- package/.claude/skills/cfn-docker-redis-coordination/src/index.ts +0 -42
- package/.claude/skills/cfn-docker-redis-coordination/src/types.ts +0 -351
- package/.claude/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +0 -1464
- package/.claude/skills/cfn-docker-redis-coordination/tsconfig.json +0 -30
- package/.claude/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +0 -228
- package/.claude/skills/cfn-loop-orchestration/helpers/consensus-ts.sh +0 -104
- package/.claude/skills/cfn-loop-orchestration/helpers/consensus.sh +0 -94
- package/.claude/skills/cfn-loop-orchestration/helpers/context-injection.sh +0 -142
- package/.claude/skills/cfn-loop-orchestration/helpers/context-lookup.sh +0 -359
- package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier-ts.sh +0 -123
- package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +0 -71
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +0 -56
- package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager-ts.sh +0 -89
- package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +0 -87
- package/.claude/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +0 -104
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +0 -56
- package/.claude/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +0 -290
- package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator-ts.sh +0 -47
- package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +0 -51
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +0 -1345
- package/.claude/skills/cfn-redis-coordination/AGENT_LOGGING.md +0 -280
- package/.claude/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +0 -209
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +0 -319
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +0 -124
- package/.claude/skills/cfn-redis-coordination/config.json +0 -61
- package/.claude/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +0 -82
- package/.claude/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +0 -274
- package/.claude/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +0 -0
- package/.claude/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +0 -553
- package/.claude/skills/cfn-redis-coordination/jest.config.js +0 -23
- package/.claude/skills/cfn-redis-coordination/package-lock.json +0 -5272
- package/.claude/skills/cfn-redis-coordination/package.json +0 -45
- package/.claude/skills/cfn-redis-coordination/src/agent-logger.ts +0 -446
- package/.claude/skills/cfn-redis-coordination/src/agent-recovery.ts +0 -454
- package/.claude/skills/cfn-redis-coordination/src/completion-reporter.ts +0 -396
- package/.claude/skills/cfn-redis-coordination/src/context-manager.ts +0 -327
- package/.claude/skills/cfn-redis-coordination/src/index.ts +0 -82
- package/.claude/skills/cfn-redis-coordination/src/mode-detector.ts +0 -155
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-client.ts +0 -305
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-functions.ts +0 -283
- package/.claude/skills/cfn-redis-coordination/src/redis-client.ts +0 -654
- package/.claude/skills/cfn-redis-coordination/src/result-collector.ts +0 -437
- package/.claude/skills/cfn-redis-coordination/src/swarm-manager.ts +0 -494
- package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +0 -404
- package/.claude/skills/cfn-redis-coordination/src/task-executor.ts +0 -423
- package/.claude/skills/cfn-redis-coordination/src/types.ts +0 -235
- package/.claude/skills/cfn-redis-coordination/src/waiting-coordinator.ts +0 -587
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +0 -85
- package/.claude/skills/cfn-redis-coordination/test-connection-attempts.js +0 -70
- package/.claude/skills/cfn-redis-coordination/test-mode-simple.js +0 -121
- package/.claude/skills/cfn-redis-coordination/test-redis-check.js +0 -84
- package/.claude/skills/cfn-redis-coordination/test-task-mode-redis.cjs +0 -391
- package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +0 -788
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +0 -67
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +0 -980
- package/claude-assets/agents/typescript-specialist.md +0 -280
- package/claude-assets/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +0 -348
- package/claude-assets/skills/cfn-docker-redis-coordination/README.md +0 -294
- package/claude-assets/skills/cfn-docker-redis-coordination/SKILL.md +0 -435
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh +0 -650
- package/claude-assets/skills/cfn-docker-redis-coordination/coordinate.sh.backup-1763145142 +0 -641
- package/claude-assets/skills/cfn-docker-redis-coordination/jest.config.js +0 -37
- package/claude-assets/skills/cfn-docker-redis-coordination/package-lock.json +0 -5259
- package/claude-assets/skills/cfn-docker-redis-coordination/package.json +0 -40
- package/claude-assets/skills/cfn-docker-redis-coordination/src/coordinator.ts +0 -801
- package/claude-assets/skills/cfn-docker-redis-coordination/src/index.ts +0 -42
- package/claude-assets/skills/cfn-docker-redis-coordination/src/types.ts +0 -351
- package/claude-assets/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +0 -1464
- package/claude-assets/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +0 -228
- package/claude-assets/skills/cfn-loop-orchestration/helpers/consensus-ts.sh +0 -104
- package/claude-assets/skills/cfn-loop-orchestration/helpers/consensus.sh +0 -94
- package/claude-assets/skills/cfn-loop-orchestration/helpers/context-injection.sh +0 -142
- package/claude-assets/skills/cfn-loop-orchestration/helpers/context-lookup.sh +0 -359
- package/claude-assets/skills/cfn-loop-orchestration/helpers/deliverable-verifier-ts.sh +0 -123
- package/claude-assets/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +0 -71
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +0 -56
- package/claude-assets/skills/cfn-loop-orchestration/helpers/iteration-manager-ts.sh +0 -89
- package/claude-assets/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +0 -87
- package/claude-assets/skills/cfn-loop-orchestration/helpers/orchestrate-ts.sh +0 -104
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +0 -56
- package/claude-assets/skills/cfn-loop-orchestration/helpers/spawn-agents.sh +0 -290
- package/claude-assets/skills/cfn-loop-orchestration/helpers/timeout-calculator-ts.sh +0 -47
- package/claude-assets/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +0 -51
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +0 -1345
- package/claude-assets/skills/cfn-redis-cleanup/cleanup-redis.sh +0 -130
- package/claude-assets/skills/cfn-redis-coordination/AGENT_LOGGING.md +0 -280
- package/claude-assets/skills/cfn-redis-coordination/BZPOPMIN_FIX_SUMMARY.md +0 -209
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +0 -319
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +0 -124
- package/claude-assets/skills/cfn-redis-coordination/config.json +0 -61
- package/claude-assets/skills/cfn-redis-coordination/demos/phase4-wake-queue-test-report.md +0 -82
- package/claude-assets/skills/cfn-redis-coordination/demos/test-bzpopmin-fix.sh +0 -274
- package/claude-assets/skills/cfn-redis-coordination/demos/test-cancel-swarm.sh +0 -0
- package/claude-assets/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +0 -553
- package/claude-assets/skills/cfn-redis-coordination/jest.config.js +0 -23
- package/claude-assets/skills/cfn-redis-coordination/package-lock.json +0 -5272
- package/claude-assets/skills/cfn-redis-coordination/package.json +0 -45
- package/claude-assets/skills/cfn-redis-coordination/src/agent-logger.ts +0 -446
- package/claude-assets/skills/cfn-redis-coordination/src/agent-recovery.ts +0 -454
- package/claude-assets/skills/cfn-redis-coordination/src/completion-reporter.ts +0 -396
- package/claude-assets/skills/cfn-redis-coordination/src/context-manager.ts +0 -327
- package/claude-assets/skills/cfn-redis-coordination/src/index.ts +0 -82
- package/claude-assets/skills/cfn-redis-coordination/src/mode-detector.ts +0 -155
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-client.ts +0 -305
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-functions.ts +0 -283
- package/claude-assets/skills/cfn-redis-coordination/src/redis-client.ts +0 -654
- package/claude-assets/skills/cfn-redis-coordination/src/result-collector.ts +0 -437
- package/claude-assets/skills/cfn-redis-coordination/src/swarm-manager.ts +0 -494
- package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +0 -404
- package/claude-assets/skills/cfn-redis-coordination/src/task-executor.ts +0 -423
- package/claude-assets/skills/cfn-redis-coordination/src/types.ts +0 -235
- package/claude-assets/skills/cfn-redis-coordination/src/waiting-coordinator.ts +0 -587
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +0 -85
- package/claude-assets/skills/cfn-redis-coordination/test-connection-attempts.js +0 -70
- package/claude-assets/skills/cfn-redis-coordination/test-mode-simple.js +0 -121
- package/claude-assets/skills/cfn-redis-coordination/test-redis-check.js +0 -84
- package/claude-assets/skills/cfn-redis-coordination/test-task-mode-redis.cjs +0 -391
- package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +0 -788
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +0 -67
- package/claude-assets/skills/cfn-redis-data-extraction/SKILL.md +0 -442
- package/claude-assets/skills/cfn-redis-data-extraction/extract.sh +0 -306
- package/dist/coordination/index.js +0 -25
- package/dist/coordination/index.js.map +0 -1
- package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +0 -405
- package/docs/MEMORY_CLEANUP_GUIDE.md +0 -358
- package/docs/MEMORY_LEAK_FIX_SUMMARY.md +0 -322
- package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +0 -319
- package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +0 -574
- /package/.claude/skills/cfn-loop-orchestration/{inject-loop-context.sh → archive/legacy-bash/inject-loop-context.sh} +0 -0
- /package/.claude/skills/cfn-loop-orchestration/{monitor-execution.sh → archive/legacy-bash/monitor-execution.sh} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{agent-log.sh → agent-log.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{agent-recovery.sh → agent-recovery.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{analyze-task-complexity.sh → analyze-task-complexity.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/bash-wrappers/{store-context.sh → store-context.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cancel-swarm.sh → cancel-swarm.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cfn-loop-exec.sh → cfn-loop-exec.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{cfn-loop-relaunch.sh → cfn-loop-relaunch.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{collect-confidence-scores.sh → collect-confidence-scores.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{collect-results.sh → collect-results.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{complete-swarm.sh → complete-swarm.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{get-context.sh → get-context.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{get-success-criteria.sh → get-success-criteria.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{invoke-waiting-mode.sh → invoke-waiting-mode.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{redis-cli-wrapper.sh → redis-cli-wrapper.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{redis-functions.sh → redis-functions.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{report-completion.sh → report-completion.sh.backup} +0 -0
- /package/.claude/skills/cfn-redis-coordination/{store-context.sh → store-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-loop-orchestration/{inject-loop-context.sh → archive/legacy-bash/inject-loop-context.sh} +0 -0
- /package/claude-assets/skills/cfn-loop-orchestration/{monitor-execution.sh → archive/legacy-bash/monitor-execution.sh} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{agent-log.sh → agent-log.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{agent-recovery.sh → agent-recovery.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{analyze-task-complexity.sh → analyze-task-complexity.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/bash-wrappers/{store-context.sh → store-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cancel-swarm.sh → cancel-swarm.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cfn-loop-exec.sh → cfn-loop-exec.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{cfn-loop-relaunch.sh → cfn-loop-relaunch.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{collect-confidence-scores.sh → collect-confidence-scores.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{collect-results.sh → collect-results.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{complete-swarm.sh → complete-swarm.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{get-context.sh → get-context.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{get-success-criteria.sh → get-success-criteria.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{invoke-waiting-mode.sh → invoke-waiting-mode.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{redis-cli-wrapper.sh → redis-cli-wrapper.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{redis-functions.sh → redis-functions.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{report-completion.sh → report-completion.sh.backup} +0 -0
- /package/claude-assets/skills/cfn-redis-coordination/{store-context.sh → store-context.sh.backup} +0 -0
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Service
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive authentication service with JWT tokens, refresh tokens,
|
|
5
|
+
* session management, and security features.
|
|
6
|
+
*/ import * as bcrypt from 'bcrypt';
|
|
7
|
+
import * as jwt from 'jsonwebtoken';
|
|
8
|
+
import { createLogger } from '../lib/logging.js';
|
|
9
|
+
import { StandardError, ErrorCode } from '../lib/errors.js';
|
|
10
|
+
import { AuthMiddleware } from '../middleware/auth-middleware.js';
|
|
11
|
+
const logger = createLogger('authentication-service');
|
|
12
|
+
export class AuthenticationService {
|
|
13
|
+
redis;
|
|
14
|
+
database;
|
|
15
|
+
authMiddleware;
|
|
16
|
+
config;
|
|
17
|
+
constructor(config){
|
|
18
|
+
this.redis = config.redis;
|
|
19
|
+
this.database = config.database;
|
|
20
|
+
this.authMiddleware = new AuthMiddleware(config.jwtSecret);
|
|
21
|
+
this.config = {
|
|
22
|
+
jwtExpiration: config.jwtExpiration || '15m',
|
|
23
|
+
refreshExpiration: config.refreshExpiration || '7d',
|
|
24
|
+
maxSessionsPerUser: config.maxSessionsPerUser || 3,
|
|
25
|
+
maxLoginAttempts: config.maxLoginAttempts || 5,
|
|
26
|
+
lockoutDuration: config.lockoutDuration || 15 * 60 * 1000
|
|
27
|
+
};
|
|
28
|
+
this.initializeDatabase();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Initialize database tables for user management
|
|
32
|
+
*/ initializeDatabase() {
|
|
33
|
+
try {
|
|
34
|
+
this.database.exec(`
|
|
35
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
36
|
+
id TEXT PRIMARY KEY,
|
|
37
|
+
username TEXT NOT NULL UNIQUE,
|
|
38
|
+
email TEXT NOT NULL UNIQUE,
|
|
39
|
+
password_hash TEXT NOT NULL,
|
|
40
|
+
role TEXT NOT NULL DEFAULT 'developer',
|
|
41
|
+
is_active BOOLEAN DEFAULT true,
|
|
42
|
+
failed_login_attempts INTEGER DEFAULT 0,
|
|
43
|
+
locked_until TIMESTAMP,
|
|
44
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
45
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
46
|
+
last_login TIMESTAMP
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_users_active ON users(is_active);
|
|
52
|
+
`);
|
|
53
|
+
logger.info('Database tables initialized for authentication service');
|
|
54
|
+
} catch (error) {
|
|
55
|
+
logger.error('Failed to initialize database tables:', error);
|
|
56
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to initialize authentication service', {}, error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Register a new user
|
|
61
|
+
*/ async registerUser(userData) {
|
|
62
|
+
try {
|
|
63
|
+
// Validate input
|
|
64
|
+
this.validateRegistrationData(userData);
|
|
65
|
+
// Check if user already exists
|
|
66
|
+
const existingUser = this.database.prepare(`
|
|
67
|
+
SELECT id FROM users WHERE email = ? OR username = ?
|
|
68
|
+
`).get(userData.email, userData.username);
|
|
69
|
+
if (existingUser) {
|
|
70
|
+
throw new StandardError(ErrorCode.CONFLICT, 'User with this email or username already exists', {
|
|
71
|
+
field: existingUser.id ? 'email' : 'username'
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Hash password
|
|
75
|
+
const passwordHash = await bcrypt.hash(userData.password, 12);
|
|
76
|
+
// Create user
|
|
77
|
+
const userId = this.generateId();
|
|
78
|
+
const now = new Date().toISOString();
|
|
79
|
+
this.database.prepare(`
|
|
80
|
+
INSERT INTO users (id, username, email, password_hash, role, created_at, updated_at)
|
|
81
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
82
|
+
`).run(userId, userData.username, userData.email, passwordHash, userData.role || 'developer', now, now);
|
|
83
|
+
const user = {
|
|
84
|
+
id: userId,
|
|
85
|
+
username: userData.username,
|
|
86
|
+
email: userData.email,
|
|
87
|
+
role: userData.role || 'developer',
|
|
88
|
+
createdAt: new Date(now)
|
|
89
|
+
};
|
|
90
|
+
// Generate tokens
|
|
91
|
+
const tokens = await this.generateTokenPair(user);
|
|
92
|
+
logger.info('User registered successfully', {
|
|
93
|
+
userId,
|
|
94
|
+
email: userData.email
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
user,
|
|
98
|
+
tokens
|
|
99
|
+
};
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error instanceof StandardError) {
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
logger.error('User registration failed:', error);
|
|
105
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Registration failed', {}, error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Authenticate user and generate tokens
|
|
110
|
+
*/ async loginUser(loginData, ipAddress, userAgent) {
|
|
111
|
+
try {
|
|
112
|
+
// Get user by email
|
|
113
|
+
const user = this.database.prepare(`
|
|
114
|
+
SELECT id, username, email, password_hash, role, is_active, failed_login_attempts, locked_until
|
|
115
|
+
FROM users WHERE email = ?
|
|
116
|
+
`).get(loginData.email);
|
|
117
|
+
if (!user) {
|
|
118
|
+
await this.recordFailedLogin(loginData.email, ipAddress);
|
|
119
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid email or password', {
|
|
120
|
+
code: 'INVALID_CREDENTIALS'
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Check if account is locked
|
|
124
|
+
if (user.locked_until && new Date(user.locked_until) > new Date()) {
|
|
125
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Account temporarily locked due to too many failed login attempts', {
|
|
126
|
+
code: 'ACCOUNT_LOCKED',
|
|
127
|
+
lockedUntil: user.locked_until
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Check if account is active
|
|
131
|
+
if (!user.is_active) {
|
|
132
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Account is deactivated', {
|
|
133
|
+
code: 'ACCOUNT_DEACTIVATED'
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Verify password
|
|
137
|
+
const isPasswordValid = await bcrypt.compare(loginData.password, user.password_hash);
|
|
138
|
+
if (!isPasswordValid) {
|
|
139
|
+
await this.recordFailedLogin(loginData.email, ipAddress);
|
|
140
|
+
await this.incrementFailedAttempts(user.id);
|
|
141
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid email or password', {
|
|
142
|
+
code: 'INVALID_CREDENTIALS'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// Reset failed attempts on successful login
|
|
146
|
+
await this.resetFailedAttempts(user.id);
|
|
147
|
+
// Update last login
|
|
148
|
+
this.database.prepare(`
|
|
149
|
+
UPDATE users SET last_login = ?, updated_at = ? WHERE id = ?
|
|
150
|
+
`).run(new Date().toISOString(), new Date().toISOString(), user.id);
|
|
151
|
+
const userProfile = {
|
|
152
|
+
id: user.id,
|
|
153
|
+
username: user.username,
|
|
154
|
+
email: user.email,
|
|
155
|
+
role: user.role,
|
|
156
|
+
createdAt: new Date(user.created_at),
|
|
157
|
+
lastLogin: new Date()
|
|
158
|
+
};
|
|
159
|
+
// Manage concurrent sessions
|
|
160
|
+
await this.manageConcurrentSessions(user.id);
|
|
161
|
+
// Generate tokens
|
|
162
|
+
const tokens = await this.generateTokenPair(userProfile, ipAddress, userAgent);
|
|
163
|
+
logger.info('User logged in successfully', {
|
|
164
|
+
userId: user.id,
|
|
165
|
+
email: user.email,
|
|
166
|
+
ipAddress
|
|
167
|
+
});
|
|
168
|
+
return {
|
|
169
|
+
user: userProfile,
|
|
170
|
+
tokens
|
|
171
|
+
};
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error instanceof StandardError) {
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
logger.error('Login failed:', error);
|
|
177
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Login failed', {}, error);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Refresh access token using refresh token
|
|
182
|
+
*/ async refreshToken(refreshToken) {
|
|
183
|
+
try {
|
|
184
|
+
// Validate refresh token
|
|
185
|
+
const tokenData = await this.validateRefreshToken(refreshToken);
|
|
186
|
+
// Get current user data
|
|
187
|
+
const user = this.database.prepare(`
|
|
188
|
+
SELECT id, username, email, role, is_active
|
|
189
|
+
FROM users WHERE id = ? AND is_active = true
|
|
190
|
+
`).get(tokenData.userId);
|
|
191
|
+
if (!user) {
|
|
192
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'User not found or inactive', {
|
|
193
|
+
code: 'USER_INACTIVE'
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const userProfile = {
|
|
197
|
+
id: user.id,
|
|
198
|
+
username: user.username,
|
|
199
|
+
email: user.email,
|
|
200
|
+
role: user.role,
|
|
201
|
+
createdAt: new Date()
|
|
202
|
+
};
|
|
203
|
+
// Generate new token pair (refresh token rotation)
|
|
204
|
+
const tokens = await this.generateTokenPair(userProfile);
|
|
205
|
+
// Invalidate old refresh token (rotation)
|
|
206
|
+
await this.invalidateRefreshToken(refreshToken);
|
|
207
|
+
logger.info('Token refreshed successfully', {
|
|
208
|
+
userId: user.id
|
|
209
|
+
});
|
|
210
|
+
return tokens;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
if (error instanceof StandardError) {
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
logger.error('Token refresh failed:', error);
|
|
216
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Token refresh failed', {}, error);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Logout user and invalidate tokens
|
|
221
|
+
*/ async logout(userId, accessToken, refreshToken) {
|
|
222
|
+
try {
|
|
223
|
+
const tokenPayload = this.authMiddleware.validateToken(accessToken);
|
|
224
|
+
// Invalidate access token (add to blacklist)
|
|
225
|
+
await this.addToBlacklist(accessToken, tokenPayload.exp);
|
|
226
|
+
// Invalidate refresh token if provided
|
|
227
|
+
if (refreshToken) {
|
|
228
|
+
await this.invalidateRefreshToken(refreshToken);
|
|
229
|
+
}
|
|
230
|
+
// Remove session
|
|
231
|
+
await this.removeSession(userId, tokenPayload.jti);
|
|
232
|
+
logger.info('User logged out successfully', {
|
|
233
|
+
userId
|
|
234
|
+
});
|
|
235
|
+
} catch (error) {
|
|
236
|
+
logger.error('Logout failed:', error);
|
|
237
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Logout failed', {}, error);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Logout from all sessions
|
|
242
|
+
*/ async logoutAllSessions(userId, accessToken) {
|
|
243
|
+
try {
|
|
244
|
+
// Get all user sessions
|
|
245
|
+
const sessionKey = `sessions:${userId}`;
|
|
246
|
+
const sessionIds = await this.redis.smembers(sessionKey);
|
|
247
|
+
// Remove all sessions
|
|
248
|
+
for (const sessionId of sessionIds){
|
|
249
|
+
await this.redis.del(`session:${sessionId}`);
|
|
250
|
+
}
|
|
251
|
+
// Clear session set
|
|
252
|
+
await this.redis.del(sessionKey);
|
|
253
|
+
// Blacklist current access token
|
|
254
|
+
const tokenPayload = this.authMiddleware.validateToken(accessToken);
|
|
255
|
+
await this.addToBlacklist(accessToken, tokenPayload.exp);
|
|
256
|
+
logger.info('All sessions terminated', {
|
|
257
|
+
userId,
|
|
258
|
+
sessionCount: sessionIds.length
|
|
259
|
+
});
|
|
260
|
+
} catch (error) {
|
|
261
|
+
logger.error('Logout all sessions failed:', error);
|
|
262
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to terminate all sessions', {}, error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get user profile
|
|
267
|
+
*/ async getUserProfile(userId) {
|
|
268
|
+
try {
|
|
269
|
+
const user = this.database.prepare(`
|
|
270
|
+
SELECT id, username, email, role, created_at, last_login
|
|
271
|
+
FROM users WHERE id = ? AND is_active = true
|
|
272
|
+
`).get(userId);
|
|
273
|
+
if (!user) {
|
|
274
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'User not found', {
|
|
275
|
+
code: 'USER_NOT_FOUND'
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
id: user.id,
|
|
280
|
+
username: user.username,
|
|
281
|
+
email: user.email,
|
|
282
|
+
role: user.role,
|
|
283
|
+
createdAt: new Date(user.created_at),
|
|
284
|
+
lastLogin: user.last_login ? new Date(user.last_login) : undefined
|
|
285
|
+
};
|
|
286
|
+
} catch (error) {
|
|
287
|
+
if (error instanceof StandardError) {
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
logger.error('Get user profile failed:', error);
|
|
291
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to get user profile', {}, error);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Update user profile
|
|
296
|
+
*/ async updateUserProfile(userId, updates) {
|
|
297
|
+
try {
|
|
298
|
+
// Validate updates
|
|
299
|
+
if (updates.username) {
|
|
300
|
+
this.validateUsername(updates.username);
|
|
301
|
+
// Check if username is already taken
|
|
302
|
+
const existingUser = this.database.prepare(`
|
|
303
|
+
SELECT id FROM users WHERE username = ? AND id != ?
|
|
304
|
+
`).get(updates.username, userId);
|
|
305
|
+
if (existingUser) {
|
|
306
|
+
throw new StandardError(ErrorCode.CONFLICT, 'Username already taken', {
|
|
307
|
+
field: 'username'
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (updates.email) {
|
|
312
|
+
this.validateEmail(updates.email);
|
|
313
|
+
// Check if email is already taken
|
|
314
|
+
const existingUser = this.database.prepare(`
|
|
315
|
+
SELECT id FROM users WHERE email = ? AND id != ?
|
|
316
|
+
`).get(updates.email, userId);
|
|
317
|
+
if (existingUser) {
|
|
318
|
+
throw new StandardError(ErrorCode.CONFLICT, 'Email already taken', {
|
|
319
|
+
field: 'email'
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Build update query
|
|
324
|
+
const fields = [];
|
|
325
|
+
const values = [];
|
|
326
|
+
if (updates.username) {
|
|
327
|
+
fields.push('username = ?');
|
|
328
|
+
values.push(updates.username);
|
|
329
|
+
}
|
|
330
|
+
if (updates.email) {
|
|
331
|
+
fields.push('email = ?');
|
|
332
|
+
values.push(updates.email);
|
|
333
|
+
}
|
|
334
|
+
fields.push('updated_at = ?');
|
|
335
|
+
values.push(new Date().toISOString());
|
|
336
|
+
values.push(userId);
|
|
337
|
+
// Update user
|
|
338
|
+
if (fields.length > 1) {
|
|
339
|
+
this.database.prepare(`
|
|
340
|
+
UPDATE users SET ${fields.join(', ')} WHERE id = ?
|
|
341
|
+
`).run(...values);
|
|
342
|
+
}
|
|
343
|
+
// Return updated profile
|
|
344
|
+
return await this.getUserProfile(userId);
|
|
345
|
+
} catch (error) {
|
|
346
|
+
if (error instanceof StandardError) {
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
logger.error('Update user profile failed:', error);
|
|
350
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to update profile', {}, error);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Change user password
|
|
355
|
+
*/ async changePassword(userId, currentPassword, newPassword) {
|
|
356
|
+
try {
|
|
357
|
+
// Validate new password
|
|
358
|
+
this.validatePasswordStrength(newPassword);
|
|
359
|
+
// Get current user
|
|
360
|
+
const user = this.database.prepare(`
|
|
361
|
+
SELECT id, password_hash
|
|
362
|
+
FROM users WHERE id = ? AND is_active = true
|
|
363
|
+
`).get(userId);
|
|
364
|
+
if (!user) {
|
|
365
|
+
throw new StandardError(ErrorCode.NOT_FOUND, 'User not found', {
|
|
366
|
+
code: 'USER_NOT_FOUND'
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
// Verify current password
|
|
370
|
+
const isCurrentPasswordValid = await bcrypt.compare(currentPassword, user.password_hash);
|
|
371
|
+
if (!isCurrentPasswordValid) {
|
|
372
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Current password is incorrect', {
|
|
373
|
+
code: 'INVALID_CURRENT_PASSWORD'
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
// Hash new password
|
|
377
|
+
const newPasswordHash = await bcrypt.hash(newPassword, 12);
|
|
378
|
+
// Update password
|
|
379
|
+
this.database.prepare(`
|
|
380
|
+
UPDATE users SET password_hash = ?, updated_at = ? WHERE id = ?
|
|
381
|
+
`).run(newPasswordHash, new Date().toISOString(), userId);
|
|
382
|
+
// Invalidate all sessions (force re-login)
|
|
383
|
+
await this.logoutAllSessions(userId, '');
|
|
384
|
+
logger.info('Password changed successfully', {
|
|
385
|
+
userId
|
|
386
|
+
});
|
|
387
|
+
} catch (error) {
|
|
388
|
+
if (error instanceof StandardError) {
|
|
389
|
+
throw error;
|
|
390
|
+
}
|
|
391
|
+
logger.error('Change password failed:', error);
|
|
392
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to change password', {}, error);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Generate token pair for user
|
|
397
|
+
*/ async generateTokenPair(user, ipAddress, userAgent) {
|
|
398
|
+
try {
|
|
399
|
+
// Generate access token
|
|
400
|
+
const accessToken = this.authMiddleware.generateToken(user.id, user.username, user.role, user.email);
|
|
401
|
+
// Generate refresh token
|
|
402
|
+
const refreshToken = jwt.sign({
|
|
403
|
+
userId: user.id,
|
|
404
|
+
type: 'refresh',
|
|
405
|
+
sessionId: this.generateId()
|
|
406
|
+
}, process.env.JWT_SECRET || 'default-secret', {
|
|
407
|
+
expiresIn: this.config.refreshExpiration
|
|
408
|
+
});
|
|
409
|
+
// Store refresh token in Redis
|
|
410
|
+
const refreshKey = `refresh:${refreshToken}`;
|
|
411
|
+
const refreshData = {
|
|
412
|
+
userId: user.id,
|
|
413
|
+
type: 'refresh',
|
|
414
|
+
ipAddress,
|
|
415
|
+
userAgent,
|
|
416
|
+
createdAt: new Date().toISOString()
|
|
417
|
+
};
|
|
418
|
+
await this.redis.setex(refreshKey, this.parseExpiration(this.config.refreshExpiration), JSON.stringify(refreshData));
|
|
419
|
+
// Store session
|
|
420
|
+
const sessionId = this.generateId();
|
|
421
|
+
const sessionKey = `session:${sessionId}`;
|
|
422
|
+
const sessionData = {
|
|
423
|
+
userId: user.id,
|
|
424
|
+
username: user.username,
|
|
425
|
+
email: user.email,
|
|
426
|
+
role: user.role,
|
|
427
|
+
ipAddress,
|
|
428
|
+
userAgent,
|
|
429
|
+
createdAt: new Date().toISOString()
|
|
430
|
+
};
|
|
431
|
+
await this.redis.setex(sessionKey, this.parseExpiration(this.config.jwtExpiration), JSON.stringify(sessionData));
|
|
432
|
+
// Add session to user's session set
|
|
433
|
+
await this.redis.sadd(`sessions:${user.id}`, sessionId);
|
|
434
|
+
await this.redis.expire(`sessions:${user.id}`, this.parseExpiration(this.config.refreshExpiration));
|
|
435
|
+
return {
|
|
436
|
+
accessToken,
|
|
437
|
+
refreshToken,
|
|
438
|
+
expiresIn: this.parseExpiration(this.config.jwtExpiration),
|
|
439
|
+
tokenType: 'Bearer'
|
|
440
|
+
};
|
|
441
|
+
} catch (error) {
|
|
442
|
+
logger.error('Token generation failed:', error);
|
|
443
|
+
throw new StandardError(ErrorCode.INTERNAL_ERROR, 'Failed to generate tokens', {}, error);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Validate refresh token
|
|
448
|
+
*/ async validateRefreshToken(refreshToken) {
|
|
449
|
+
try {
|
|
450
|
+
// Check if refresh token exists in Redis
|
|
451
|
+
const refreshKey = `refresh:${refreshToken}`;
|
|
452
|
+
const tokenData = await this.redis.get(refreshKey);
|
|
453
|
+
if (!tokenData) {
|
|
454
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid or expired refresh token', {
|
|
455
|
+
code: 'INVALID_REFRESH_TOKEN'
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
// Verify JWT token
|
|
459
|
+
const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET || 'default-secret');
|
|
460
|
+
if (decoded.type !== 'refresh') {
|
|
461
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid token type', {
|
|
462
|
+
code: 'INVALID_TOKEN_TYPE'
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
return decoded;
|
|
466
|
+
} catch (error) {
|
|
467
|
+
if (error instanceof StandardError) {
|
|
468
|
+
throw error;
|
|
469
|
+
}
|
|
470
|
+
if (error instanceof jwt.TokenExpiredError) {
|
|
471
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Refresh token has expired', {
|
|
472
|
+
code: 'REFRESH_TOKEN_EXPIRED'
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
if (error instanceof jwt.JsonWebTokenError) {
|
|
476
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid refresh token', {
|
|
477
|
+
code: 'INVALID_REFRESH_TOKEN'
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
throw error;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Invalidate refresh token
|
|
485
|
+
*/ async invalidateRefreshToken(refreshToken) {
|
|
486
|
+
try {
|
|
487
|
+
const refreshKey = `refresh:${refreshToken}`;
|
|
488
|
+
await this.redis.del(refreshKey);
|
|
489
|
+
} catch (error) {
|
|
490
|
+
logger.error('Failed to invalidate refresh token:', error);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Add token to blacklist
|
|
495
|
+
*/ async addToBlacklist(token, expirationTime) {
|
|
496
|
+
try {
|
|
497
|
+
const blacklistKey = `blacklist:${this.hashToken(token)}`;
|
|
498
|
+
const ttl = expirationTime - Math.floor(Date.now() / 1000);
|
|
499
|
+
if (ttl > 0) {
|
|
500
|
+
await this.redis.setex(blacklistKey, ttl, '1');
|
|
501
|
+
}
|
|
502
|
+
} catch (error) {
|
|
503
|
+
logger.error('Failed to add token to blacklist:', error);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Remove session
|
|
508
|
+
*/ async removeSession(userId, sessionId) {
|
|
509
|
+
try {
|
|
510
|
+
await this.redis.del(`session:${sessionId}`);
|
|
511
|
+
await this.redis.srem(`sessions:${userId}`, sessionId);
|
|
512
|
+
} catch (error) {
|
|
513
|
+
logger.error('Failed to remove session:', error);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Manage concurrent sessions
|
|
518
|
+
*/ async manageConcurrentSessions(userId) {
|
|
519
|
+
try {
|
|
520
|
+
const sessionKey = `sessions:${userId}`;
|
|
521
|
+
const sessionIds = await this.redis.smembers(sessionKey);
|
|
522
|
+
if (sessionIds.length >= this.config.maxSessionsPerUser) {
|
|
523
|
+
// Remove oldest session
|
|
524
|
+
const oldestSessionId = sessionIds[0];
|
|
525
|
+
await this.removeSession(userId, oldestSessionId);
|
|
526
|
+
}
|
|
527
|
+
} catch (error) {
|
|
528
|
+
logger.error('Failed to manage concurrent sessions:', error);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Record failed login attempt
|
|
533
|
+
*/ async recordFailedLogin(email, ipAddress) {
|
|
534
|
+
try {
|
|
535
|
+
const key = `failed_login:${email}:${ipAddress || 'unknown'}`;
|
|
536
|
+
await this.redis.incr(key);
|
|
537
|
+
await this.redis.expire(key, this.config.lockoutDuration / 1000);
|
|
538
|
+
} catch (error) {
|
|
539
|
+
logger.error('Failed to record failed login:', error);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Increment failed login attempts for user
|
|
544
|
+
*/ async incrementFailedAttempts(userId) {
|
|
545
|
+
try {
|
|
546
|
+
const user = this.database.prepare(`
|
|
547
|
+
SELECT failed_login_attempts FROM users WHERE id = ?
|
|
548
|
+
`).get(userId);
|
|
549
|
+
if (user) {
|
|
550
|
+
const newAttempts = user.failed_login_attempts + 1;
|
|
551
|
+
const lockedUntil = newAttempts >= this.config.maxLoginAttempts ? new Date(Date.now() + this.config.lockoutDuration).toISOString() : null;
|
|
552
|
+
this.database.prepare(`
|
|
553
|
+
UPDATE users SET failed_login_attempts = ?, locked_until = ?, updated_at = ?
|
|
554
|
+
WHERE id = ?
|
|
555
|
+
`).run(newAttempts, lockedUntil, new Date().toISOString(), userId);
|
|
556
|
+
}
|
|
557
|
+
} catch (error) {
|
|
558
|
+
logger.error('Failed to increment failed attempts:', error);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Reset failed login attempts for user
|
|
563
|
+
*/ async resetFailedAttempts(userId) {
|
|
564
|
+
try {
|
|
565
|
+
this.database.prepare(`
|
|
566
|
+
UPDATE users SET failed_login_attempts = 0, locked_until = null, updated_at = ?
|
|
567
|
+
WHERE id = ?
|
|
568
|
+
`).run(new Date().toISOString(), userId);
|
|
569
|
+
} catch (error) {
|
|
570
|
+
logger.error('Failed to reset failed attempts:', error);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Validation methods
|
|
575
|
+
*/ validateRegistrationData(data) {
|
|
576
|
+
if (!data.username || data.username.trim().length < 3) {
|
|
577
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Username must be at least 3 characters long', {
|
|
578
|
+
field: 'username'
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
this.validateUsername(data.username);
|
|
582
|
+
this.validateEmail(data.email);
|
|
583
|
+
this.validatePasswordStrength(data.password);
|
|
584
|
+
if (data.role && ![
|
|
585
|
+
'admin',
|
|
586
|
+
'developer',
|
|
587
|
+
'readonly'
|
|
588
|
+
].includes(data.role)) {
|
|
589
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid role specified', {
|
|
590
|
+
field: 'role'
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
validateUsername(username) {
|
|
595
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(username)) {
|
|
596
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Username can only contain letters, numbers, underscores, and hyphens', {
|
|
597
|
+
field: 'username'
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
validateEmail(email) {
|
|
602
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
603
|
+
if (!emailRegex.test(email)) {
|
|
604
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Invalid email format', {
|
|
605
|
+
field: 'email'
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
validatePasswordStrength(password) {
|
|
610
|
+
if (password.length < 8) {
|
|
611
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Password must be at least 8 characters long', {
|
|
612
|
+
field: 'password'
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
if (!/[A-Z]/.test(password)) {
|
|
616
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Password must contain at least one uppercase letter', {
|
|
617
|
+
field: 'password'
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
if (!/[a-z]/.test(password)) {
|
|
621
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Password must contain at least one lowercase letter', {
|
|
622
|
+
field: 'password'
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
if (!/\d/.test(password)) {
|
|
626
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Password must contain at least one number', {
|
|
627
|
+
field: 'password'
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
|
|
631
|
+
throw new StandardError(ErrorCode.VALIDATION_FAILED, 'Password must contain at least one special character', {
|
|
632
|
+
field: 'password'
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Utility methods
|
|
638
|
+
*/ generateId() {
|
|
639
|
+
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
640
|
+
}
|
|
641
|
+
parseExpiration(expiration) {
|
|
642
|
+
const match = expiration.match(/^(\d+)([smhd])$/);
|
|
643
|
+
if (!match) {
|
|
644
|
+
return 3600; // Default to 1 hour
|
|
645
|
+
}
|
|
646
|
+
const value = parseInt(match[1], 10);
|
|
647
|
+
const unit = match[2];
|
|
648
|
+
switch(unit){
|
|
649
|
+
case 's':
|
|
650
|
+
return value;
|
|
651
|
+
case 'm':
|
|
652
|
+
return value * 60;
|
|
653
|
+
case 'h':
|
|
654
|
+
return value * 3600;
|
|
655
|
+
case 'd':
|
|
656
|
+
return value * 86400;
|
|
657
|
+
default:
|
|
658
|
+
return 3600;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
hashToken(token) {
|
|
662
|
+
return token.split('').reduce((acc, char)=>{
|
|
663
|
+
acc = (acc << 5) - acc + char.charCodeAt(0);
|
|
664
|
+
return acc & acc;
|
|
665
|
+
}, 0).toString(36);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
//# sourceMappingURL=authentication.js.map
|