claude-flow-novice 2.15.4 → 2.15.6
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/.gs-api-quota.json +16 -0
- package/.claude/cfn-extras/.gs-progress-state.json +22 -0
- package/.claude/cfn-extras/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +414 -0
- package/.claude/cfn-extras/agents/google-sheets/README.md +114 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-advanced-analytics-specialist.md +288 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-api-integrator.md +127 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-automation-scripting-specialist.md +195 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-business-validator.md +179 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-collaboration-security-specialist.md +240 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-coordinator.md +214 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-transformer.md +127 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-validation-quality-specialist.md +177 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-validator.md +119 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-visualization-specialist.md +135 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-design-layout-specialist.md +109 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-engineer.md +127 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-engineering-specialist.md +138 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-validator.md +128 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-generalist.md +645 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-integration-api-specialist.md +258 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-performance-analyst.md +125 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-performance-optimization-specialist.md +211 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-schema-designer.md +130 -0
- package/.claude/cfn-extras/agents/google-sheets/google-sheets-template-architecture-specialist.md +259 -0
- package/.claude/cfn-extras/docs/GOOGLE_SHEETS_CFN_LOOP.md +617 -0
- package/.claude/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +453 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +272 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/api-call.sh +254 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/test.sh +174 -0
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/validate.sh +98 -0
- package/.claude/cfn-extras/skills/google-sheets-decomposition/SKILL.md +269 -0
- package/.claude/cfn-extras/skills/google-sheets-decomposition/decompose.sh +313 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +237 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/build-formula.sh +220 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/test.sh +172 -0
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/validate.sh +98 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/SKILL.md +287 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/test.sh +385 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/track-progress.sh +516 -0
- package/.claude/cfn-extras/skills/google-sheets-progress/validate.sh +119 -0
- package/.claude/cfn-extras/skills/google-sheets-sprint-order/SKILL.md +277 -0
- package/.claude/cfn-extras/skills/google-sheets-sprint-order/order-sprints.sh +233 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/SKILL.md +352 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/test.sh +355 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/validate-state.sh +374 -0
- package/.claude/cfn-extras/skills/google-sheets-validation/validate.sh +128 -0
- package/.claude/commands/cfn-context.md +10 -0
- package/.claude/commands/cfn-loop-cli.md +44 -14
- package/.claude/commands/google-sheets/google-sheets-loop.md +289 -0
- package/.claude/skills/cfn-agent-selector/SKILL.md +143 -0
- package/.claude/skills/cfn-agent-selector/select-agents.sh +94 -0
- package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -2
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +21 -2
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +11 -5
- package/.claude/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +348 -0
- package/.claude/skills/cfn-docker-redis-coordination/README.md +294 -0
- package/.claude/skills/cfn-docker-redis-coordination/jest.config.js +37 -0
- package/.claude/skills/cfn-docker-redis-coordination/package-lock.json +5259 -0
- package/.claude/skills/cfn-docker-redis-coordination/package.json +40 -0
- package/.claude/skills/cfn-docker-redis-coordination/src/coordinator.ts +801 -0
- package/.claude/skills/cfn-docker-redis-coordination/src/index.ts +42 -0
- package/.claude/skills/cfn-docker-redis-coordination/src/types.ts +351 -0
- package/.claude/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +1464 -0
- package/.claude/skills/cfn-docker-redis-coordination/tsconfig.json +30 -0
- package/.claude/skills/cfn-loop-orchestration/.eslintrc.js +56 -0
- package/.claude/skills/cfn-loop-orchestration/.prettierrc.json +18 -0
- package/.claude/skills/cfn-loop-orchestration/README.md +149 -41
- package/.claude/skills/cfn-loop-orchestration/jest.config.js +67 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate-wrapper.sh +268 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +147 -16
- package/.claude/skills/cfn-loop-orchestration/package-lock.json +5470 -0
- package/.claude/skills/cfn-loop-orchestration/package.json +49 -0
- package/.claude/skills/cfn-loop-orchestration/src/agent-spawner/agent-spawner.ts +34 -0
- package/.claude/skills/cfn-loop-orchestration/src/gate-checker/gate-checker.ts +36 -0
- package/.claude/skills/cfn-loop-orchestration/src/index.ts +14 -0
- package/.claude/skills/cfn-loop-orchestration/src/orchestrator/orchestrator.ts +31 -0
- package/.claude/skills/cfn-loop-orchestration/src/redis/redis-coordinator.ts +72 -0
- package/.claude/skills/cfn-loop-orchestration/src/types.ts +188 -0
- package/.claude/skills/cfn-loop-orchestration/src/utils/logger.ts +32 -0
- package/.claude/skills/cfn-loop-orchestration/tests/setup.ts +22 -0
- package/.claude/skills/cfn-loop-orchestration/tests/types.test.ts +132 -0
- package/.claude/skills/cfn-loop-orchestration/tsconfig.json +54 -0
- package/.claude/skills/cfn-redis-coordination/bash-wrappers/store-context.sh +23 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.d.ts +92 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.js +329 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-logger.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.d.ts +75 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.js +302 -0
- package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.d.ts +58 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.js +237 -0
- package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.d.ts +63 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.js +230 -0
- package/.claude/skills/cfn-redis-coordination/dist/context-manager.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.d.ts +45 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.js +114 -0
- package/.claude/skills/cfn-redis-coordination/dist/index.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.d.ts +31 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.js +185 -0
- package/.claude/skills/cfn-redis-coordination/dist/mode-detector.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.d.ts +191 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.js +509 -0
- package/.claude/skills/cfn-redis-coordination/dist/redis-client.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.d.ts +75 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.js +281 -0
- package/.claude/skills/cfn-redis-coordination/dist/result-collector.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.d.ts +75 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.js +354 -0
- package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.d.ts +62 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js +305 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.d.ts +97 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.js +283 -0
- package/.claude/skills/cfn-redis-coordination/dist/task-executor.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.d.ts +176 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.js +81 -0
- package/.claude/skills/cfn-redis-coordination/dist/types.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts +86 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts.map +1 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.js +419 -0
- package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.js.map +1 -0
- package/.claude/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +553 -0
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -2
- package/.claude/skills/cfn-redis-coordination/jest.config.js +23 -0
- package/.claude/skills/cfn-redis-coordination/package-lock.json +5272 -0
- package/.claude/skills/cfn-redis-coordination/package.json +45 -0
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +21 -8
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +3 -2
- package/.claude/skills/cfn-redis-coordination/src/agent-logger.ts +446 -0
- package/.claude/skills/cfn-redis-coordination/src/agent-recovery.ts +454 -0
- package/.claude/skills/cfn-redis-coordination/src/completion-reporter.ts +396 -0
- package/.claude/skills/cfn-redis-coordination/src/context-manager.ts +327 -0
- package/.claude/skills/cfn-redis-coordination/src/index.ts +82 -0
- package/.claude/skills/cfn-redis-coordination/src/mode-detector.ts +155 -0
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-client.ts +305 -0
- package/.claude/skills/cfn-redis-coordination/src/redis/redis-functions.ts +283 -0
- package/.claude/skills/cfn-redis-coordination/src/redis-client.ts +654 -0
- package/.claude/skills/cfn-redis-coordination/src/result-collector.ts +437 -0
- package/.claude/skills/cfn-redis-coordination/src/swarm-manager.ts +494 -0
- package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +404 -0
- package/.claude/skills/cfn-redis-coordination/src/task-executor.ts +423 -0
- package/.claude/skills/cfn-redis-coordination/src/types.ts +235 -0
- package/.claude/skills/cfn-redis-coordination/src/waiting-coordinator.ts +587 -0
- package/.claude/skills/cfn-redis-coordination/test-connection-attempts.js +70 -0
- package/.claude/skills/cfn-redis-coordination/test-mode-simple.js +121 -0
- package/.claude/skills/cfn-redis-coordination/test-redis-check.js +84 -0
- package/.claude/skills/cfn-redis-coordination/test-task-mode-redis.cjs +391 -0
- package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +779 -0
- package/.claude/skills/cfn-redis-coordination/tsconfig.json +31 -0
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +172 -2
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +1 -1
- package/claude-assets/agents/custom/cfn-redis-operations.md +530 -0
- package/claude-assets/agents/custom/cfn-system-expert.md +77 -0
- package/claude-assets/cfn-extras/.gs-api-quota.json +16 -0
- package/claude-assets/cfn-extras/.gs-progress-state.json +22 -0
- package/claude-assets/cfn-extras/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +414 -0
- package/claude-assets/cfn-extras/agents/google-sheets/README.md +114 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-advanced-analytics-specialist.md +288 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-api-integrator.md +127 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-automation-scripting-specialist.md +195 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-business-validator.md +179 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-collaboration-security-specialist.md +240 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-coordinator.md +214 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-transformer.md +127 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-validation-quality-specialist.md +177 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-validator.md +119 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-visualization-specialist.md +135 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-design-layout-specialist.md +109 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-engineer.md +127 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-engineering-specialist.md +138 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-validator.md +128 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-generalist.md +645 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-integration-api-specialist.md +258 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-performance-analyst.md +125 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-performance-optimization-specialist.md +211 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-schema-designer.md +130 -0
- package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-template-architecture-specialist.md +259 -0
- package/claude-assets/cfn-extras/docs/GOOGLE_SHEETS_CFN_LOOP.md +617 -0
- package/claude-assets/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +453 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +272 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/api-call.sh +254 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/test.sh +174 -0
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/validate.sh +98 -0
- package/claude-assets/cfn-extras/skills/google-sheets-decomposition/SKILL.md +269 -0
- package/claude-assets/cfn-extras/skills/google-sheets-decomposition/decompose.sh +313 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +237 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/build-formula.sh +220 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/test.sh +172 -0
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/validate.sh +98 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/SKILL.md +287 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/test.sh +385 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/track-progress.sh +516 -0
- package/claude-assets/cfn-extras/skills/google-sheets-progress/validate.sh +119 -0
- package/claude-assets/cfn-extras/skills/google-sheets-sprint-order/SKILL.md +277 -0
- package/claude-assets/cfn-extras/skills/google-sheets-sprint-order/order-sprints.sh +233 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/SKILL.md +352 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/test.sh +355 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/validate-state.sh +374 -0
- package/claude-assets/cfn-extras/skills/google-sheets-validation/validate.sh +128 -0
- package/claude-assets/commands/cfn-context.md +10 -0
- package/claude-assets/commands/cfn-loop-cli.md +44 -14
- package/claude-assets/commands/google-sheets/google-sheets-loop.md +289 -0
- package/claude-assets/hooks/cfn-pre-execution/SESSION_START_README.md +87 -0
- package/claude-assets/hooks/cfn-pre-execution/TEST_SESSION_START.md +128 -0
- package/claude-assets/hooks/cfn-pre-execution/session-start-context.sh +111 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/INTEGRATION_EXAMPLE.md +209 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/README.md +130 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md +243 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/agent-mappings.json +142 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh +173 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh +71 -0
- package/claude-assets/skills/cfn-agent-selection-with-fallback/test-agent-selection.sh +282 -0
- package/claude-assets/skills/cfn-agent-selector/SKILL.md +143 -0
- package/claude-assets/skills/cfn-agent-selector/select-agents.sh +94 -0
- package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -2
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +21 -2
- package/claude-assets/skills/cfn-docker-coordination/.eslintrc.json +33 -0
- package/claude-assets/skills/cfn-docker-coordination/README.md +349 -0
- package/claude-assets/skills/cfn-docker-coordination/docker-helpers.sh +433 -0
- package/claude-assets/skills/cfn-docker-coordination/jest.config.js +25 -0
- package/claude-assets/skills/cfn-docker-coordination/package-lock.json +6827 -0
- package/claude-assets/skills/cfn-docker-coordination/package.json +38 -0
- package/claude-assets/skills/cfn-docker-coordination/src/agent-container.ts +471 -0
- package/claude-assets/skills/cfn-docker-coordination/src/docker-client.ts +483 -0
- package/claude-assets/skills/cfn-docker-coordination/src/health-checker.ts +418 -0
- package/claude-assets/skills/cfn-docker-coordination/src/index.ts +45 -0
- package/claude-assets/skills/cfn-docker-coordination/src/network-manager.ts +377 -0
- package/claude-assets/skills/cfn-docker-coordination/src/types.ts +412 -0
- package/claude-assets/skills/cfn-docker-coordination/src/volume-manager.ts +389 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/agent-container.test.ts +379 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/docker-client.test.ts +345 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/health-checker.test.ts +535 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/integration.test.ts +193 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/network-manager.test.ts +352 -0
- package/claude-assets/skills/cfn-docker-coordination/tests/setup.ts +36 -0
- package/claude-assets/skills/cfn-docker-coordination/tsconfig.json +29 -0
- package/claude-assets/skills/cfn-docker-logging/INTEGRATION.md +268 -0
- package/claude-assets/skills/cfn-docker-logging/SAMPLE_OUTPUTS.md +237 -0
- package/claude-assets/skills/cfn-docker-logging/SKILL.md +442 -0
- package/claude-assets/skills/cfn-docker-logging/capture-container-logs.sh +120 -0
- package/claude-assets/skills/cfn-docker-logging/enable-logging.sh +430 -0
- package/claude-assets/skills/cfn-docker-logging/init-hybrid-logging.sh +210 -0
- package/claude-assets/skills/cfn-docker-logging/queries/analytics-summary.sh +87 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-agent-timeline.sh +51 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-consensus-history.sh +56 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-coordination-timeline.sh +39 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-failed-containers.sh +40 -0
- package/claude-assets/skills/cfn-docker-logging/queries/query-gate-checks.sh +39 -0
- package/claude-assets/skills/cfn-docker-logging/schema.sql +111 -0
- package/claude-assets/skills/cfn-docker-logging/sqlite-helpers.sh +240 -0
- package/claude-assets/skills/cfn-docker-logging/test-hybrid-logging.sh +331 -0
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +11 -5
- package/claude-assets/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +348 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/README.md +294 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/jest.config.js +37 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/package-lock.json +5259 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/package.json +40 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/src/coordinator.ts +801 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/src/index.ts +42 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/src/types.ts +351 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +1464 -0
- package/claude-assets/skills/cfn-docker-redis-coordination/tsconfig.json +30 -0
- package/claude-assets/skills/cfn-error-logging/.eslintrc.json +57 -0
- package/claude-assets/skills/cfn-error-logging/.prettierrc.json +10 -0
- package/claude-assets/skills/cfn-error-logging/MIGRATION_SUMMARY.md +485 -0
- package/claude-assets/skills/cfn-error-logging/package.json +47 -0
- package/claude-assets/skills/cfn-error-logging/src/error-logger.ts +1042 -0
- package/claude-assets/skills/cfn-error-logging/src/index.ts +12 -0
- package/claude-assets/skills/cfn-error-logging/src/types.ts +456 -0
- package/claude-assets/skills/cfn-error-logging/tests/error-logger.test.ts +1302 -0
- package/claude-assets/skills/cfn-error-logging/tsconfig.json +38 -0
- package/claude-assets/skills/cfn-loop-orchestration/.eslintrc.js +56 -0
- package/claude-assets/skills/cfn-loop-orchestration/.prettierrc.json +18 -0
- package/claude-assets/skills/cfn-loop-orchestration/README.md +149 -41
- package/claude-assets/skills/cfn-loop-orchestration/jest.config.js +67 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate-wrapper.sh +268 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +147 -16
- package/claude-assets/skills/cfn-loop-orchestration/package-lock.json +5470 -0
- package/claude-assets/skills/cfn-loop-orchestration/package.json +49 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/agent-spawner/agent-spawner.ts +34 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/gate-checker/gate-checker.ts +36 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/index.ts +14 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/orchestrator/orchestrator.ts +31 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/redis/redis-coordinator.ts +72 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/types.ts +188 -0
- package/claude-assets/skills/cfn-loop-orchestration/src/utils/logger.ts +32 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/setup.ts +22 -0
- package/claude-assets/skills/cfn-loop-orchestration/tests/types.test.ts +132 -0
- package/claude-assets/skills/cfn-loop-orchestration/tsconfig.json +54 -0
- package/claude-assets/skills/cfn-redis-coordination/bash-wrappers/store-context.sh +23 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.d.ts +92 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.js +329 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.d.ts +75 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.js +302 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.d.ts +58 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.js +237 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.d.ts +63 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.js +230 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.d.ts +45 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.js +114 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/index.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.d.ts +31 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.js +185 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.d.ts +191 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.js +509 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.d.ts +75 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.js +281 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.d.ts +75 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.js +354 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.d.ts +62 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js +305 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.d.ts +97 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.js +283 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.d.ts +176 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.js +81 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/types.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts +86 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.js +419 -0
- package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.js.map +1 -0
- package/claude-assets/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +553 -0
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -2
- package/claude-assets/skills/cfn-redis-coordination/jest.config.js +23 -0
- package/claude-assets/skills/cfn-redis-coordination/package-lock.json +5272 -0
- package/claude-assets/skills/cfn-redis-coordination/package.json +45 -0
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +21 -8
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +3 -2
- package/claude-assets/skills/cfn-redis-coordination/src/agent-logger.ts +446 -0
- package/claude-assets/skills/cfn-redis-coordination/src/agent-recovery.ts +454 -0
- package/claude-assets/skills/cfn-redis-coordination/src/completion-reporter.ts +396 -0
- package/claude-assets/skills/cfn-redis-coordination/src/context-manager.ts +327 -0
- package/claude-assets/skills/cfn-redis-coordination/src/index.ts +82 -0
- package/claude-assets/skills/cfn-redis-coordination/src/mode-detector.ts +155 -0
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-client.ts +305 -0
- package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-functions.ts +283 -0
- package/claude-assets/skills/cfn-redis-coordination/src/redis-client.ts +654 -0
- package/claude-assets/skills/cfn-redis-coordination/src/result-collector.ts +437 -0
- package/claude-assets/skills/cfn-redis-coordination/src/swarm-manager.ts +494 -0
- package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +404 -0
- package/claude-assets/skills/cfn-redis-coordination/src/task-executor.ts +423 -0
- package/claude-assets/skills/cfn-redis-coordination/src/types.ts +235 -0
- package/claude-assets/skills/cfn-redis-coordination/src/waiting-coordinator.ts +587 -0
- package/claude-assets/skills/cfn-redis-coordination/test-connection-attempts.js +70 -0
- package/claude-assets/skills/cfn-redis-coordination/test-mode-simple.js +121 -0
- package/claude-assets/skills/cfn-redis-coordination/test-redis-check.js +84 -0
- package/claude-assets/skills/cfn-redis-coordination/test-task-mode-redis.cjs +391 -0
- package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +779 -0
- package/claude-assets/skills/cfn-redis-coordination/tsconfig.json +31 -0
- package/claude-assets/skills/cfn-skill-propagation/README.md +233 -0
- package/claude-assets/skills/cfn-skill-propagation/package-lock.json +5174 -0
- package/claude-assets/skills/cfn-skill-propagation/package.json +52 -0
- package/claude-assets/skills/cfn-skill-propagation/propagate-skill-update.sh +32 -0
- package/claude-assets/skills/cfn-skill-propagation/src/cli.ts +75 -0
- package/claude-assets/skills/cfn-skill-propagation/src/database-adapter.ts +239 -0
- package/claude-assets/skills/cfn-skill-propagation/src/file-system-adapter.ts +113 -0
- package/claude-assets/skills/cfn-skill-propagation/src/index.ts +72 -0
- package/claude-assets/skills/cfn-skill-propagation/src/logger.ts +43 -0
- package/claude-assets/skills/cfn-skill-propagation/src/metadata-parser.ts +154 -0
- package/claude-assets/skills/cfn-skill-propagation/src/skill-propagator.ts +274 -0
- package/claude-assets/skills/cfn-skill-propagation/src/skill-validator.ts +179 -0
- package/claude-assets/skills/cfn-skill-propagation/src/types.ts +143 -0
- package/claude-assets/skills/cfn-skill-propagation/src/version-manager.ts +118 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/file-system-adapter.test.ts +91 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/metadata-parser.test.ts +176 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/skill-propagator.test.ts +209 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/skill-validator.test.ts +203 -0
- package/claude-assets/skills/cfn-skill-propagation/tests/version-manager.test.ts +115 -0
- package/claude-assets/skills/cfn-skill-propagation/tsconfig.json +34 -0
- package/claude-assets/skills/task-classifier/SKILL.md +81 -0
- package/claude-assets/skills/task-classifier/classify-task.sh +62 -0
- package/claude-assets/skills/workflow-codification/package-lock.json +5170 -0
- package/claude-assets/skills/workflow-codification/package.json +30 -0
- package/claude-assets/skills/workflow-codification/src/index.ts +24 -0
- package/claude-assets/skills/workflow-codification/src/pattern-analyzer.ts +537 -0
- package/claude-assets/skills/workflow-codification/src/types.ts +180 -0
- package/claude-assets/skills/workflow-codification/tests/pattern-analyzer.test.ts +960 -0
- package/claude-assets/skills/workflow-codification/tsconfig.json +34 -0
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/agent-spawner/agent-spawner.js +448 -0
- package/dist/agent-spawner/agent-spawner.js.map +1 -0
- package/dist/agent-spawner/index.js +10 -0
- package/dist/agent-spawner/index.js.map +1 -0
- package/dist/agent-spawner/types.js +14 -0
- package/dist/agent-spawner/types.js.map +1 -0
- package/dist/cli/agent-executor.js +47 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-spawn.js +4 -1
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/config-manager.js +109 -91
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/conversation-fork-cleanup.js +201 -0
- package/dist/cli/conversation-fork-cleanup.js.map +1 -0
- package/dist/cli/conversation-fork.js +16 -3
- package/dist/cli/conversation-fork.js.map +1 -1
- package/dist/cli/tool-executor.js +3 -1
- package/dist/cli/tool-executor.js.map +1 -1
- package/dist/gate-checker/gate-checker.js +292 -0
- package/dist/gate-checker/gate-checker.js.map +1 -0
- package/dist/gate-checker/types.js +94 -0
- package/dist/gate-checker/types.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +2 -1
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -1
- package/dist/orchestrator/index.js +10 -0
- package/dist/orchestrator/index.js.map +1 -0
- package/dist/orchestrator/orchestrate.js +496 -0
- package/dist/orchestrator/orchestrate.js.map +1 -0
- package/dist/orchestrator/types.js +58 -0
- package/dist/orchestrator/types.js.map +1 -0
- package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +405 -0
- package/docs/MEMORY_CLEANUP_GUIDE.md +358 -0
- package/docs/MEMORY_LEAK_FIX_SUMMARY.md +322 -0
- package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +319 -0
- package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +574 -0
- package/package.json +208 -201
- package/readme/README.md +34 -1
- package/scripts/switch-api.sh +142 -4
- package/scripts/verify-no-secrets.sh +6 -13
- package/scripts/verify-redis-cleanup.sh +173 -0
- package/tests/README.md +201 -0
- package/tests/test-memory-leak-task-mode.sh +435 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/config-manager.ts"],"sourcesContent":["import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport Ajv from \"ajv\";\nimport * as lodash from \"lodash\";\n\ninterface ConfigSchema {\n redis: {\n host: string;\n port: number;\n password?: string;\n };\n agent: {\n default_strategy: string;\n max_concurrent_agents: number;\n log_level: \"debug\" | \"info\" | \"warn\" | \"error\";\n };\n security: {\n enabled: boolean;\n max_retry_attempts: number;\n };\n}\n\nclass ConfigManager {\n private static _instance: ConfigManager | null = null;\n private configPath: string;\n private schemaPath: string;\n private ajv: Ajv;\n\n private constructor() {\n this.configPath = path.join(\n process.env.HOME || \"\",\n \".claude-flow-config.json\",\n );\n this.schemaPath = path.join(\n __dirname,\n \"../../.claude/skills/config-management/config.json\",\n );\n this.ajv = new Ajv();\n }\n\n public static getInstance(): ConfigManager {\n if (!ConfigManager._instance) {\n ConfigManager._instance = new ConfigManager();\n }\n return ConfigManager._instance;\n }\n\n private async readConfig(): Promise<ConfigSchema> {\n try {\n const configContent = await fs.readFile(this.configPath, \"utf-8\");\n return JSON.parse(configContent) as ConfigSchema;\n } catch (error) {\n // If config doesn't exist, create from schema\n return this.resetToDefaults();\n }\n }\n\n private async writeConfig(config: ConfigSchema): Promise<void> {\n const schemaContent = await fs.readFile(this.schemaPath, \"utf-8\");\n const schema = JSON.parse(schemaContent);\n\n const validate = this.ajv.compile(schema);\n if (!validate(config)) {\n throw new Error(\n \"Invalid configuration: \" + this.ajv.errorsText(validate.errors),\n );\n }\n\n await fs.writeFile(\n this.configPath,\n JSON.stringify(config, null, 2),\n \"utf-8\",\n );\n }\n\n public async getValue(keyPath: string): Promise<any> {\n const config = await this.readConfig();\n const value = lodash.get(config, keyPath);\n\n if (value === undefined) {\n // Check if it's a custom key path not in the schema\n const customConfig = await this.readCustomConfig();\n return lodash.get(customConfig, keyPath);\n }\n\n return value;\n }\n\n private async readCustomConfig(): Promise<Record<string, any>> {\n try {\n const customConfigPath = path.join(\n process.env.HOME || \"\",\n \".claude-flow-custom-config.json\",\n );\n const customConfigContent = await fs.readFile(customConfigPath, \"utf-8\");\n return JSON.parse(customConfigContent);\n } catch (error) {\n // If custom config doesn't exist or can't be read, return empty object\n return {};\n }\n }\n\n public async set(key: keyof ConfigSchema, value: ConfigSchema[keyof ConfigSchema]): Promise<void> {\n const config = await this.readConfig();\n\n // Type assertion to handle full object\n if (typeof value === \"object\" && value !== null) {\n config[key] = value;\n } else {\n throw new Error(\"Invalid configuration value\");\n }\n\n await this.writeConfig(config);\n }\n\n public async getAll(): Promise<ConfigSchema> {\n return this.readConfig();\n }\n\n public async resetToDefaults(): Promise<ConfigSchema> {\n const schemaContent = await fs.readFile(this.schemaPath, \"utf-8\");\n const schema = JSON.parse(schemaContent);\n\n // Extract default values from the schema\n const defaultConfig: ConfigSchema = {\n redis: {\n host: schema.properties.redis.properties.host.default,\n port: schema.properties.redis.properties.port.default,\n },\n agent: {\n default_strategy:\n schema.properties.agent.properties.default_strategy.default,\n max_concurrent_agents:\n schema.properties.agent.properties.max_concurrent_agents.default,\n log_level: schema.properties.agent.properties.log_level.default,\n },\n security: {\n enabled: schema.properties.security.properties.enabled.default,\n max_retry_attempts:\n schema.properties.security.properties.max_retry_attempts.default,\n },\n };\n\n await this.writeConfig(defaultConfig);\n return defaultConfig;\n }\n}\n\nexport default ConfigManager;"],"names":["fs","path","Ajv","lodash","ConfigManager","_instance","configPath","schemaPath","ajv","join","process","env","HOME","__dirname","getInstance","readConfig","configContent","readFile","JSON","parse","error","resetToDefaults","writeConfig","config","schemaContent","schema","validate","compile","Error","errorsText","errors","writeFile","stringify","getValue","keyPath","value","get","undefined","customConfig","readCustomConfig","customConfigPath","customConfigContent","set","key","getAll","defaultConfig","redis","host","properties","default","port","agent","default_strategy","max_concurrent_agents","log_level","security","enabled","max_retry_attempts"],"mappings":"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"} config = _a.sent();\n // Type assertion to handle both full object and nested key\n if (typeof value === \"object\" && value !== null) {\n config[key] = value;\n }\n else {\n throw new Error(\"Invalid configuration value\");\n }\n return [4 /*yield*/, this.writeConfig(config)];\n case 2:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.getAll = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, this.readConfig()];\n });\n });\n };\n ConfigManager.prototype.resetToDefaults = function () {\n return __awaiter(this, void 0, void 0, function () {\n var schemaContent, schema, defaultConfig;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fs.readFile(this.schemaPath, \"utf-8\")];\n case 1:\n schemaContent = _a.sent();\n schema = JSON.parse(schemaContent);\n defaultConfig = {\n redis: {\n host: schema.properties.redis.properties.host.default,\n port: schema.properties.redis.properties.port.default,\n },\n agent: {\n default_strategy: schema.properties.agent.properties.default_strategy.default,\n max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,\n log_level: schema.properties.agent.properties.log_level.default,\n },\n security: {\n enabled: schema.properties.security.properties.enabled.default,\n max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default,\n },\n };\n return [4 /*yield*/, this.writeConfig(defaultConfig)];\n case 2:\n _a.sent();\n return [2 /*return*/, defaultConfig];\n }\n });\n });\n };\n return ConfigManager;\n}());\nexports.default = ConfigManager;\n"],"names":["__awaiter","thisArg","_arguments","P","generator","adopt","value","resolve","Promise","reject","fulfilled","step","next","e","rejected","result","done","then","apply","__generator","body","_","label","sent","t","trys","ops","f","y","g","Object","create","Iterator","prototype","verb","Symbol","iterator","n","v","op","TypeError","call","pop","length","push","defineProperty","exports","fs","require","path","ajv_1","get_1","ConfigManager","configPath","join","process","env","HOME","schemaPath","__dirname","ajv","default","getInstance","instance","readConfig","configContent","error_1","_a","readFile","JSON","parse","resetToDefaults","writeConfig","config","schemaContent","schema","validate","compile","Error","errorsText","errors","writeFile","stringify","getValue","keyPath","customConfig","undefined","readCustomConfig","customConfigPath","customConfigContent","error_2","set","key","getAll","defaultConfig","redis","host","properties","port","agent","default_strategy","max_concurrent_agents","log_level","security","enabled","max_retry_attempts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/config-manager.js"],"sourcesContent":["\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (this && this.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar fs = require(\"fs/promises\");\nvar path = require(\"path\");\nvar ajv_1 = require(\"ajv\");\nvar get_1 = require(\"lodash/get\");\nvar ConfigManager = /** @class */ (function () {\n function ConfigManager() {\n this.configPath = path.join(process.env.HOME || \"\", \".claude-flow-config.json\");\n this.schemaPath = path.join(__dirname, \"../../.claude/skills/config-management/config.json\");\n this.ajv = new ajv_1.default();\n }\n ConfigManager.getInstance = function () {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n };\n ConfigManager.prototype.readConfig = function () {\n return __awaiter(this, void 0, void 0, function () {\n var configContent, error_1;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n _a.trys.push([0, 2, , 3]);\n return [4 /*yield*/, fs.readFile(this.configPath, \"utf-8\")];\n case 1:\n configContent = _a.sent();\n return [2 /*return*/, JSON.parse(configContent)];\n case 2:\n error_1 = _a.sent();\n // If config doesn't exist, create from schema\n return [2 /*return*/, this.resetToDefaults()];\n case 3: return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.writeConfig = function (config) {\n return __awaiter(this, void 0, void 0, function () {\n var schemaContent, schema, validate;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fs.readFile(this.schemaPath, \"utf-8\")];\n case 1:\n schemaContent = _a.sent();\n schema = JSON.parse(schemaContent);\n validate = this.ajv.compile(schema);\n if (!validate(config)) {\n throw new Error(\"Invalid configuration: \" + this.ajv.errorsText(validate.errors));\n }\n return [4 /*yield*/, fs.writeFile(this.configPath, JSON.stringify(config, null, 2), \"utf-8\")];\n case 2:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.getValue = function (keyPath) {\n return __awaiter(this, void 0, void 0, function () {\n var config, value, customConfig;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.readConfig()];\n case 1:\n config = _a.sent();\n value = (0, get_1.default)(config, keyPath);\n if (!(value === undefined)) return [3 /*break*/, 3];\n return [4 /*yield*/, this.readCustomConfig()];\n case 2:\n customConfig = _a.sent();\n return [2 /*return*/, (0, get_1.default)(customConfig, keyPath)];\n case 3: return [2 /*return*/, value];\n }\n });\n });\n };\n ConfigManager.prototype.readCustomConfig = function () {\n return __awaiter(this, void 0, void 0, function () {\n var customConfigPath, customConfigContent, error_2;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n _a.trys.push([0, 2, , 3]);\n customConfigPath = path.join(process.env.HOME || \"\", \".claude-flow-custom-config.json\");\n return [4 /*yield*/, fs.readFile(customConfigPath, \"utf-8\")];\n case 1:\n customConfigContent = _a.sent();\n return [2 /*return*/, JSON.parse(customConfigContent)];\n case 2:\n error_2 = _a.sent();\n // If custom config doesn't exist or can't be read, return empty object\n return [2 /*return*/, {}];\n case 3: return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.set = function (key, value) {\n return __awaiter(this, void 0, void 0, function () {\n var config;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.readConfig()];\n case 1:\n config = _a.sent();\n // Type assertion to handle both full object and nested key\n if (typeof value === \"object\" && value !== null) {\n config[key] = value;\n }\n else {\n throw new Error(\"Invalid configuration value\");\n }\n return [4 /*yield*/, this.writeConfig(config)];\n case 2:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.getAll = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, this.readConfig()];\n });\n });\n };\n ConfigManager.prototype.resetToDefaults = function () {\n return __awaiter(this, void 0, void 0, function () {\n var schemaContent, schema, defaultConfig;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fs.readFile(this.schemaPath, \"utf-8\")];\n case 1:\n schemaContent = _a.sent();\n schema = JSON.parse(schemaContent);\n defaultConfig = {\n redis: {\n host: schema.properties.redis.properties.host.default,\n port: schema.properties.redis.properties.port.default,\n },\n agent: {\n default_strategy: schema.properties.agent.properties.default_strategy.default,\n max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,\n log_level: schema.properties.agent.properties.log_level.default,\n },\n security: {\n enabled: schema.properties.security.properties.enabled.default,\n max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default,\n },\n };\n return [4 /*yield*/, this.writeConfig(defaultConfig)];\n case 2:\n _a.sent();\n return [2 /*return*/, defaultConfig];\n }\n });\n });\n };\n return ConfigManager;\n}());\nexports.default = ConfigManager;\n"],"names":["__awaiter","thisArg","_arguments","P","generator","adopt","value","resolve","Promise","reject","fulfilled","step","next","e","rejected","result","done","then","apply","__generator","body","_","label","sent","t","trys","ops","f","y","g","Object","create","Iterator","prototype","verb","Symbol","iterator","n","v","op","TypeError","call","pop","length","push","defineProperty","exports","fs","require","path","ajv_1","get_1","ConfigManager","configPath","join","process","env","HOME","schemaPath","__dirname","ajv","default","getInstance","instance","readConfig","configContent","error_1","_a","readFile","JSON","parse","resetToDefaults","writeConfig","config","schemaContent","schema","validate","compile","Error","errorsText","errors","writeFile","stringify","getValue","keyPath","customConfig","undefined","readCustomConfig","customConfigPath","customConfigContent","error_2","set","key","getAll","defaultConfig","redis","host","properties","port","agent","default_strategy","max_concurrent_agents","log_level","security","enabled","max_retry_attempts"],"mappings":"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"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation Fork Cleanup Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides memory leak prevention for Task Mode by:
|
|
5
|
+
* 1. Setting TTL on message lists (24h default)
|
|
6
|
+
* 2. Cleaning up completed task messages
|
|
7
|
+
* 3. Limiting message history size
|
|
8
|
+
* 4. Auto-cleanup of orphaned forks
|
|
9
|
+
*/ import { execSync } from 'child_process';
|
|
10
|
+
const redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';
|
|
11
|
+
const redisPort = process.env.CFN_REDIS_PORT || '6379';
|
|
12
|
+
const DEFAULT_OPTIONS = {
|
|
13
|
+
messageTTL: 86400,
|
|
14
|
+
maxMessagesPerAgent: 100,
|
|
15
|
+
autoCleanupForks: true
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Set TTL on message list to prevent indefinite accumulation
|
|
19
|
+
*/ export function setMessageListTTL(taskId, agentId, ttlSeconds = DEFAULT_OPTIONS.messageTTL) {
|
|
20
|
+
const key = `swarm:${taskId}:${agentId}:messages`;
|
|
21
|
+
try {
|
|
22
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire "${key}" ${ttlSeconds}`, {
|
|
23
|
+
encoding: 'utf8'
|
|
24
|
+
});
|
|
25
|
+
console.log(`[conversation-cleanup] Set TTL ${ttlSeconds}s on ${key}`);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error(`[conversation-cleanup] Failed to set TTL:`, error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Trim message list to max size (FIFO - keep recent messages)
|
|
32
|
+
*/ export function trimMessageList(taskId, agentId, maxMessages = DEFAULT_OPTIONS.maxMessagesPerAgent) {
|
|
33
|
+
const key = `swarm:${taskId}:${agentId}:messages`;
|
|
34
|
+
try {
|
|
35
|
+
// Keep only the last N messages (0 = oldest, -N = keep last N)
|
|
36
|
+
const start = -maxMessages;
|
|
37
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} ltrim "${key}" ${start} -1`, {
|
|
38
|
+
encoding: 'utf8'
|
|
39
|
+
});
|
|
40
|
+
console.log(`[conversation-cleanup] Trimmed ${key} to ${maxMessages} messages`);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(`[conversation-cleanup] Failed to trim messages:`, error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Clean up all messages and forks for a completed task
|
|
47
|
+
*/ export function cleanupTaskMessages(taskId, agentId) {
|
|
48
|
+
try {
|
|
49
|
+
// Delete main message list
|
|
50
|
+
const messagesKey = `swarm:${taskId}:${agentId}:messages`;
|
|
51
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} del "${messagesKey}"`, {
|
|
52
|
+
encoding: 'utf8'
|
|
53
|
+
});
|
|
54
|
+
// Delete all fork message lists
|
|
55
|
+
const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;
|
|
56
|
+
const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkPattern}"`, {
|
|
57
|
+
encoding: 'utf8'
|
|
58
|
+
}).trim().split('\n').filter((k)=>k);
|
|
59
|
+
if (forkKeys.length > 0) {
|
|
60
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${forkKeys.join(' ')}`, {
|
|
61
|
+
encoding: 'utf8'
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Delete all fork metadata
|
|
65
|
+
const forkMetaPattern = `swarm:${taskId}:${agentId}:fork:*:meta`;
|
|
66
|
+
const metaKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkMetaPattern}"`, {
|
|
67
|
+
encoding: 'utf8'
|
|
68
|
+
}).trim().split('\n').filter((k)=>k);
|
|
69
|
+
if (metaKeys.length > 0) {
|
|
70
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${metaKeys.join(' ')}`, {
|
|
71
|
+
encoding: 'utf8'
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Delete current fork pointer
|
|
75
|
+
const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;
|
|
76
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} del "${currentForkKey}"`, {
|
|
77
|
+
encoding: 'utf8'
|
|
78
|
+
});
|
|
79
|
+
console.log(`[conversation-cleanup] Cleaned up task ${taskId} agent ${agentId}`);
|
|
80
|
+
console.log(`[conversation-cleanup] Removed: 1 message list, ${forkKeys.length} fork snapshots, ${metaKeys.length} fork metadata`);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(`[conversation-cleanup] Failed to cleanup task messages:`, error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Clean up orphaned forks (metadata expired but messages remain)
|
|
87
|
+
*/ export function cleanupOrphanedForks(taskId, agentId) {
|
|
88
|
+
try {
|
|
89
|
+
// Find all fork message keys
|
|
90
|
+
const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;
|
|
91
|
+
const forkMessageKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkPattern}"`, {
|
|
92
|
+
encoding: 'utf8'
|
|
93
|
+
}).trim().split('\n').filter((k)=>k);
|
|
94
|
+
if (forkMessageKeys.length === 0) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const orphanedKeys = [];
|
|
98
|
+
for (const messageKey of forkMessageKeys){
|
|
99
|
+
// Extract fork ID from key: swarm:task:agent:fork:FORK_ID:messages
|
|
100
|
+
const parts = messageKey.split(':');
|
|
101
|
+
const forkId = parts[parts.length - 2];
|
|
102
|
+
// Check if metadata exists
|
|
103
|
+
const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;
|
|
104
|
+
const metaExists = execSync(`redis-cli -h ${redisHost} -p ${redisPort} exists "${metaKey}"`, {
|
|
105
|
+
encoding: 'utf8'
|
|
106
|
+
}).trim();
|
|
107
|
+
if (metaExists === '0') {
|
|
108
|
+
// Metadata expired but messages remain = orphaned
|
|
109
|
+
orphanedKeys.push(messageKey);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (orphanedKeys.length > 0) {
|
|
113
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${orphanedKeys.join(' ')}`, {
|
|
114
|
+
encoding: 'utf8'
|
|
115
|
+
});
|
|
116
|
+
console.log(`[conversation-cleanup] Removed ${orphanedKeys.length} orphaned fork snapshots`);
|
|
117
|
+
}
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error(`[conversation-cleanup] Failed to cleanup orphaned forks:`, error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get memory usage statistics for a task
|
|
124
|
+
*/ export function getTaskMemoryStats(taskId, agentId) {
|
|
125
|
+
try {
|
|
126
|
+
// Count messages in main list
|
|
127
|
+
const messagesKey = `swarm:${taskId}:${agentId}:messages`;
|
|
128
|
+
const messageCount = parseInt(execSync(`redis-cli -h ${redisHost} -p ${redisPort} llen "${messagesKey}"`, {
|
|
129
|
+
encoding: 'utf8'
|
|
130
|
+
}).trim(), 10);
|
|
131
|
+
// Count forks
|
|
132
|
+
const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;
|
|
133
|
+
const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkPattern}"`, {
|
|
134
|
+
encoding: 'utf8'
|
|
135
|
+
}).trim().split('\n').filter((k)=>k);
|
|
136
|
+
// Estimate size (average message ~5KB)
|
|
137
|
+
const estimatedSizeKB = messageCount * 5;
|
|
138
|
+
return {
|
|
139
|
+
messageCount,
|
|
140
|
+
forkCount: forkKeys.length,
|
|
141
|
+
estimatedSizeKB
|
|
142
|
+
};
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(`[conversation-cleanup] Failed to get memory stats:`, error);
|
|
145
|
+
return {
|
|
146
|
+
messageCount: 0,
|
|
147
|
+
forkCount: 0,
|
|
148
|
+
estimatedSizeKB: 0
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Configure automatic cleanup options for a task
|
|
154
|
+
*/ export function configureAutoCleanup(taskId, agentId, options = {}) {
|
|
155
|
+
const config = {
|
|
156
|
+
...DEFAULT_OPTIONS,
|
|
157
|
+
...options
|
|
158
|
+
};
|
|
159
|
+
// Set TTL on message list
|
|
160
|
+
setMessageListTTL(taskId, agentId, config.messageTTL);
|
|
161
|
+
// Trim to max size
|
|
162
|
+
trimMessageList(taskId, agentId, config.maxMessagesPerAgent);
|
|
163
|
+
// Cleanup orphaned forks
|
|
164
|
+
if (config.autoCleanupForks) {
|
|
165
|
+
cleanupOrphanedForks(taskId, agentId);
|
|
166
|
+
}
|
|
167
|
+
console.log(`[conversation-cleanup] Auto-cleanup configured for ${taskId}/${agentId}`);
|
|
168
|
+
console.log(`[conversation-cleanup] - TTL: ${config.messageTTL}s`);
|
|
169
|
+
console.log(`[conversation-cleanup] - Max messages: ${config.maxMessagesPerAgent}`);
|
|
170
|
+
console.log(`[conversation-cleanup] - Auto-cleanup forks: ${config.autoCleanupForks}`);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Emergency cleanup - remove all conversation data for all tasks
|
|
174
|
+
* USE WITH CAUTION: This will delete ALL conversation history
|
|
175
|
+
*/ export function emergencyCleanupAll() {
|
|
176
|
+
try {
|
|
177
|
+
const patterns = [
|
|
178
|
+
'swarm:*:*:messages',
|
|
179
|
+
'swarm:*:*:fork:*:messages',
|
|
180
|
+
'swarm:*:*:fork:*:meta',
|
|
181
|
+
'swarm:*:*:current-fork'
|
|
182
|
+
];
|
|
183
|
+
let totalDeleted = 0;
|
|
184
|
+
for (const pattern of patterns){
|
|
185
|
+
const keys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${pattern}"`, {
|
|
186
|
+
encoding: 'utf8'
|
|
187
|
+
}).trim().split('\n').filter((k)=>k);
|
|
188
|
+
if (keys.length > 0) {
|
|
189
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${keys.join(' ')}`, {
|
|
190
|
+
encoding: 'utf8'
|
|
191
|
+
});
|
|
192
|
+
totalDeleted += keys.length;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
console.log(`[conversation-cleanup] EMERGENCY CLEANUP: Deleted ${totalDeleted} conversation keys`);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.error(`[conversation-cleanup] Failed emergency cleanup:`, error);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
//# sourceMappingURL=conversation-fork-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/conversation-fork-cleanup.ts"],"sourcesContent":["/**\r\n * Conversation Fork Cleanup Utilities\r\n *\r\n * Provides memory leak prevention for Task Mode by:\r\n * 1. Setting TTL on message lists (24h default)\r\n * 2. Cleaning up completed task messages\r\n * 3. Limiting message history size\r\n * 4. Auto-cleanup of orphaned forks\r\n */\r\n\r\nimport { execSync } from 'child_process';\r\n\r\nconst redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\nconst redisPort = process.env.CFN_REDIS_PORT || '6379';\r\n\r\nexport interface CleanupOptions {\r\n messageTTL?: number; // TTL for message lists (seconds, default: 86400 = 24h)\r\n maxMessagesPerAgent?: number; // Max messages to keep per agent (default: 100)\r\n autoCleanupForks?: boolean; // Auto-cleanup orphaned forks (default: true)\r\n}\r\n\r\nconst DEFAULT_OPTIONS: Required<CleanupOptions> = {\r\n messageTTL: 86400, // 24 hours\r\n maxMessagesPerAgent: 100, // 100 messages = ~50 iterations\r\n autoCleanupForks: true,\r\n};\r\n\r\n/**\r\n * Set TTL on message list to prevent indefinite accumulation\r\n */\r\nexport function setMessageListTTL(\r\n taskId: string,\r\n agentId: string,\r\n ttlSeconds: number = DEFAULT_OPTIONS.messageTTL\r\n): void {\r\n const key = `swarm:${taskId}:${agentId}:messages`;\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire \"${key}\" ${ttlSeconds}`, {\r\n encoding: 'utf8'\r\n });\r\n console.log(`[conversation-cleanup] Set TTL ${ttlSeconds}s on ${key}`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to set TTL:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Trim message list to max size (FIFO - keep recent messages)\r\n */\r\nexport function trimMessageList(\r\n taskId: string,\r\n agentId: string,\r\n maxMessages: number = DEFAULT_OPTIONS.maxMessagesPerAgent\r\n): void {\r\n const key = `swarm:${taskId}:${agentId}:messages`;\r\n\r\n try {\r\n // Keep only the last N messages (0 = oldest, -N = keep last N)\r\n const start = -maxMessages;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} ltrim \"${key}\" ${start} -1`, {\r\n encoding: 'utf8'\r\n });\r\n console.log(`[conversation-cleanup] Trimmed ${key} to ${maxMessages} messages`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to trim messages:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Clean up all messages and forks for a completed task\r\n */\r\nexport function cleanupTaskMessages(taskId: string, agentId: string): void {\r\n try {\r\n // Delete main message list\r\n const messagesKey = `swarm:${taskId}:${agentId}:messages`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${messagesKey}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n // Delete all fork message lists\r\n const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;\r\n const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (forkKeys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${forkKeys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n }\r\n\r\n // Delete all fork metadata\r\n const forkMetaPattern = `swarm:${taskId}:${agentId}:fork:*:meta`;\r\n const metaKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkMetaPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (metaKeys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${metaKeys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n }\r\n\r\n // Delete current fork pointer\r\n const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${currentForkKey}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n console.log(`[conversation-cleanup] Cleaned up task ${taskId} agent ${agentId}`);\r\n console.log(`[conversation-cleanup] Removed: 1 message list, ${forkKeys.length} fork snapshots, ${metaKeys.length} fork metadata`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to cleanup task messages:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Clean up orphaned forks (metadata expired but messages remain)\r\n */\r\nexport function cleanupOrphanedForks(taskId: string, agentId: string): void {\r\n try {\r\n // Find all fork message keys\r\n const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;\r\n const forkMessageKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (forkMessageKeys.length === 0) {\r\n return;\r\n }\r\n\r\n const orphanedKeys: string[] = [];\r\n\r\n for (const messageKey of forkMessageKeys) {\r\n // Extract fork ID from key: swarm:task:agent:fork:FORK_ID:messages\r\n const parts = messageKey.split(':');\r\n const forkId = parts[parts.length - 2];\r\n\r\n // Check if metadata exists\r\n const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n const metaExists = execSync(`redis-cli -h ${redisHost} -p ${redisPort} exists \"${metaKey}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (metaExists === '0') {\r\n // Metadata expired but messages remain = orphaned\r\n orphanedKeys.push(messageKey);\r\n }\r\n }\r\n\r\n if (orphanedKeys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${orphanedKeys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n console.log(`[conversation-cleanup] Removed ${orphanedKeys.length} orphaned fork snapshots`);\r\n }\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to cleanup orphaned forks:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Get memory usage statistics for a task\r\n */\r\nexport function getTaskMemoryStats(taskId: string, agentId: string): {\r\n messageCount: number;\r\n forkCount: number;\r\n estimatedSizeKB: number;\r\n} {\r\n try {\r\n // Count messages in main list\r\n const messagesKey = `swarm:${taskId}:${agentId}:messages`;\r\n const messageCount = parseInt(execSync(`redis-cli -h ${redisHost} -p ${redisPort} llen \"${messagesKey}\"`, {\r\n encoding: 'utf8'\r\n }).trim(), 10);\r\n\r\n // Count forks\r\n const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;\r\n const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n // Estimate size (average message ~5KB)\r\n const estimatedSizeKB = messageCount * 5;\r\n\r\n return {\r\n messageCount,\r\n forkCount: forkKeys.length,\r\n estimatedSizeKB,\r\n };\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to get memory stats:`, error);\r\n return {\r\n messageCount: 0,\r\n forkCount: 0,\r\n estimatedSizeKB: 0,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Configure automatic cleanup options for a task\r\n */\r\nexport function configureAutoCleanup(\r\n taskId: string,\r\n agentId: string,\r\n options: CleanupOptions = {}\r\n): void {\r\n const config = { ...DEFAULT_OPTIONS, ...options };\r\n\r\n // Set TTL on message list\r\n setMessageListTTL(taskId, agentId, config.messageTTL);\r\n\r\n // Trim to max size\r\n trimMessageList(taskId, agentId, config.maxMessagesPerAgent);\r\n\r\n // Cleanup orphaned forks\r\n if (config.autoCleanupForks) {\r\n cleanupOrphanedForks(taskId, agentId);\r\n }\r\n\r\n console.log(`[conversation-cleanup] Auto-cleanup configured for ${taskId}/${agentId}`);\r\n console.log(`[conversation-cleanup] - TTL: ${config.messageTTL}s`);\r\n console.log(`[conversation-cleanup] - Max messages: ${config.maxMessagesPerAgent}`);\r\n console.log(`[conversation-cleanup] - Auto-cleanup forks: ${config.autoCleanupForks}`);\r\n}\r\n\r\n/**\r\n * Emergency cleanup - remove all conversation data for all tasks\r\n * USE WITH CAUTION: This will delete ALL conversation history\r\n */\r\nexport function emergencyCleanupAll(): void {\r\n try {\r\n const patterns = [\r\n 'swarm:*:*:messages',\r\n 'swarm:*:*:fork:*:messages',\r\n 'swarm:*:*:fork:*:meta',\r\n 'swarm:*:*:current-fork',\r\n ];\r\n\r\n let totalDeleted = 0;\r\n\r\n for (const pattern of patterns) {\r\n const keys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${pattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (keys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${keys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n totalDeleted += keys.length;\r\n }\r\n }\r\n\r\n console.log(`[conversation-cleanup] EMERGENCY CLEANUP: Deleted ${totalDeleted} conversation keys`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed emergency cleanup:`, error);\r\n }\r\n}\r\n"],"names":["execSync","redisHost","process","env","CFN_REDIS_HOST","redisPort","CFN_REDIS_PORT","DEFAULT_OPTIONS","messageTTL","maxMessagesPerAgent","autoCleanupForks","setMessageListTTL","taskId","agentId","ttlSeconds","key","encoding","console","log","error","trimMessageList","maxMessages","start","cleanupTaskMessages","messagesKey","forkPattern","forkKeys","trim","split","filter","k","length","join","forkMetaPattern","metaKeys","currentForkKey","cleanupOrphanedForks","forkMessageKeys","orphanedKeys","messageKey","parts","forkId","metaKey","metaExists","push","getTaskMemoryStats","messageCount","parseInt","estimatedSizeKB","forkCount","configureAutoCleanup","options","config","emergencyCleanupAll","patterns","totalDeleted","pattern","keys"],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ const redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';
|
|
|
12
12
|
const redisPort = process.env.CFN_REDIS_PORT || '6379';
|
|
13
13
|
/**
|
|
14
14
|
* Store a message in conversation history
|
|
15
|
+
* MEMORY LEAK FIX: Now sets TTL on message list to prevent indefinite accumulation
|
|
15
16
|
*/ export async function storeMessage(taskId, agentId, message) {
|
|
16
17
|
const key = `swarm:${taskId}:${agentId}:messages`;
|
|
17
18
|
const messageJson = JSON.stringify(message);
|
|
@@ -19,6 +20,12 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
|
|
|
19
20
|
execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush "${key}" '${messageJson.replace(/'/g, "'\\''")}'`, {
|
|
20
21
|
encoding: 'utf8'
|
|
21
22
|
});
|
|
23
|
+
// MEMORY LEAK FIX: Set TTL on message list (24h default)
|
|
24
|
+
// This prevents messages from accumulating indefinitely across multiple tasks
|
|
25
|
+
const messageTTL = parseInt(process.env.CFN_MESSAGE_TTL || '86400', 10); // 24 hours
|
|
26
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire "${key}" ${messageTTL}`, {
|
|
27
|
+
encoding: 'utf8'
|
|
28
|
+
});
|
|
22
29
|
} catch (error) {
|
|
23
30
|
console.error(`[conversation-fork] Failed to store message:`, error);
|
|
24
31
|
throw error;
|
|
@@ -46,6 +53,7 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
|
|
|
46
53
|
/**
|
|
47
54
|
* Create a fork from current conversation state
|
|
48
55
|
* Copies all messages up to current iteration
|
|
56
|
+
* MEMORY LEAK FIX: Now sets TTL on fork message list matching metadata TTL
|
|
49
57
|
*/ export async function createFork(taskId, agentId, currentIteration) {
|
|
50
58
|
// Generate unique fork ID
|
|
51
59
|
const forkId = `fork-${currentIteration}-${randomBytes(4).toString('hex')}`;
|
|
@@ -57,12 +65,17 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
|
|
|
57
65
|
}
|
|
58
66
|
// Store fork snapshot
|
|
59
67
|
const forkKey = `swarm:${taskId}:${agentId}:fork:${forkId}:messages`;
|
|
68
|
+
const forkTTL = parseInt(process.env.CFN_FORK_TTL || '86400', 10); // 24 hours
|
|
60
69
|
for (const message of forkMessages){
|
|
61
70
|
const messageJson = JSON.stringify(message);
|
|
62
71
|
execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush "${forkKey}" '${messageJson.replace(/'/g, "'\\''")}'`, {
|
|
63
72
|
encoding: 'utf8'
|
|
64
73
|
});
|
|
65
74
|
}
|
|
75
|
+
// MEMORY LEAK FIX: Set TTL on fork messages (was missing before)
|
|
76
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire "${forkKey}" ${forkTTL}`, {
|
|
77
|
+
encoding: 'utf8'
|
|
78
|
+
});
|
|
66
79
|
// Store fork metadata
|
|
67
80
|
const metadata = {
|
|
68
81
|
forkId,
|
|
@@ -73,15 +86,15 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
|
|
|
73
86
|
messageCount: forkMessages.length
|
|
74
87
|
};
|
|
75
88
|
const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;
|
|
76
|
-
execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${metaKey}"
|
|
89
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${metaKey}" ${forkTTL} '${JSON.stringify(metadata)}'`, {
|
|
77
90
|
encoding: 'utf8'
|
|
78
91
|
});
|
|
79
92
|
// Set as current fork
|
|
80
93
|
const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;
|
|
81
|
-
execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${currentForkKey}"
|
|
94
|
+
execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${currentForkKey}" ${forkTTL} "${forkId}"`, {
|
|
82
95
|
encoding: 'utf8'
|
|
83
96
|
});
|
|
84
|
-
console.log(`[conversation-fork] Created fork ${forkId} with ${forkMessages.length} messages`);
|
|
97
|
+
console.log(`[conversation-fork] Created fork ${forkId} with ${forkMessages.length} messages (TTL: ${forkTTL}s)`);
|
|
85
98
|
return forkId;
|
|
86
99
|
}
|
|
87
100
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/conversation-fork.ts"],"sourcesContent":["/**\r\n * Conversation Fork Management\r\n *\r\n * Implements application-level conversation forking for CFN Loop iterations.\r\n * Stores conversation history in Redis and allows branching at specific points.\r\n *\r\n * Sprint 4: Conversation Forking (v2.7.0)\r\n */\r\n\r\nimport { execSync } from 'child_process';\r\nimport { randomBytes } from 'crypto';\r\n\r\n// Bug #6 Fix: Read Redis connection parameters from process.env\r\nconst redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\nconst redisPort = process.env.CFN_REDIS_PORT || '6379';\r\n\r\nexport interface Message {\r\n role: 'user' | 'assistant';\r\n content: string;\r\n iteration: number;\r\n timestamp: string;\r\n}\r\n\r\nexport interface ForkMetadata {\r\n forkId: string;\r\n taskId: string;\r\n agentId: string;\r\n createdAt: string;\r\n parentIteration: number;\r\n messageCount: number;\r\n}\r\n\r\n/**\r\n * Store a message in conversation history\r\n */\r\nexport async function storeMessage(\r\n taskId: string,\r\n agentId: string,\r\n message: Message\r\n): Promise<void> {\r\n const key = `swarm:${taskId}:${agentId}:messages`;\r\n const messageJson = JSON.stringify(message);\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush \"${key}\" '${messageJson.replace(/'/g, \"'\\\\''\")}'`, {\r\n encoding: 'utf8'\r\n });\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to store message:`, error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Load all messages from conversation history\r\n */\r\nexport async function loadMessages(\r\n taskId: string,\r\n agentId: string,\r\n forkId?: string\r\n): Promise<Message[]> {\r\n const key = forkId\r\n ? `swarm:${taskId}:${agentId}:fork:${forkId}:messages`\r\n : `swarm:${taskId}:${agentId}:messages`;\r\n\r\n try {\r\n const output = execSync(`redis-cli -h ${redisHost} -p ${redisPort} lrange \"${key}\" 0 -1`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (!output || output === '(empty array)') {\r\n return [];\r\n }\r\n\r\n // Redis returns each message on a new line\r\n const lines = output.split('\\n');\r\n return lines.map(line => JSON.parse(line));\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to load messages:`, error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Create a fork from current conversation state\r\n * Copies all messages up to current iteration\r\n */\r\nexport async function createFork(\r\n taskId: string,\r\n agentId: string,\r\n currentIteration: number\r\n): Promise<string> {\r\n // Generate unique fork ID\r\n const forkId = `fork-${currentIteration}-${randomBytes(4).toString('hex')}`;\r\n\r\n // Load messages up to current iteration\r\n const messages = await loadMessages(taskId, agentId);\r\n const forkMessages = messages.filter(m => m.iteration <= currentIteration);\r\n\r\n if (forkMessages.length === 0) {\r\n throw new Error(`No messages found for iteration ${currentIteration}`);\r\n }\r\n\r\n // Store fork snapshot\r\n const forkKey = `swarm:${taskId}:${agentId}:fork:${forkId}:messages`;\r\n\r\n for (const message of forkMessages) {\r\n const messageJson = JSON.stringify(message);\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush \"${forkKey}\" '${messageJson.replace(/'/g, \"'\\\\''\")}'`, {\r\n encoding: 'utf8'\r\n });\r\n }\r\n\r\n // Store fork metadata\r\n const metadata: ForkMetadata = {\r\n forkId,\r\n taskId,\r\n agentId,\r\n createdAt: new Date().toISOString(),\r\n parentIteration: currentIteration,\r\n messageCount: forkMessages.length\r\n };\r\n\r\n const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex \"${metaKey}\" 86400 '${JSON.stringify(metadata)}'`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n // Set as current fork\r\n const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex \"${currentForkKey}\" 86400 \"${forkId}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n console.log(`[conversation-fork] Created fork ${forkId} with ${forkMessages.length} messages`);\r\n\r\n return forkId;\r\n}\r\n\r\n/**\r\n * Get current active fork ID\r\n */\r\nexport async function getCurrentFork(\r\n taskId: string,\r\n agentId: string\r\n): Promise<string | null> {\r\n const key = `swarm:${taskId}:${agentId}:current-fork`;\r\n\r\n try {\r\n const forkId = execSync(`redis-cli -h ${redisHost} -p ${redisPort} get \"${key}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (forkId === '(nil)' || !forkId) {\r\n return null;\r\n }\r\n\r\n return forkId;\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get fork metadata\r\n */\r\nexport async function getForkMetadata(\r\n taskId: string,\r\n agentId: string,\r\n forkId: string\r\n): Promise<ForkMetadata | null> {\r\n const key = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n\r\n try {\r\n const metaJson = execSync(`redis-cli -h ${redisHost} -p ${redisPort} get \"${key}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (metaJson === '(nil)' || !metaJson) {\r\n return null;\r\n }\r\n\r\n return JSON.parse(metaJson);\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * List all forks for an agent\r\n */\r\nexport async function listForks(\r\n taskId: string,\r\n agentId: string\r\n): Promise<ForkMetadata[]> {\r\n const pattern = `swarm:${taskId}:${agentId}:fork:*:meta`;\r\n\r\n try {\r\n const keys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${pattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n const forks: ForkMetadata[] = [];\r\n\r\n for (const key of keys) {\r\n const metaJson = execSync(`redis-cli -h ${redisHost} -p ${redisPort} get \"${key}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (metaJson && metaJson !== '(nil)') {\r\n forks.push(JSON.parse(metaJson));\r\n }\r\n }\r\n\r\n return forks.sort((a, b) =>\r\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\r\n );\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to list forks:`, error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Delete a fork and its messages\r\n */\r\nexport async function deleteFork(\r\n taskId: string,\r\n agentId: string,\r\n forkId: string\r\n): Promise<void> {\r\n const messagesKey = `swarm:${taskId}:${agentId}:fork:${forkId}:messages`;\r\n const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${messagesKey}\" \"${metaKey}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n console.log(`[conversation-fork] Deleted fork ${forkId}`);\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to delete fork:`, error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Clear current fork (start fresh conversation)\r\n */\r\nexport async function clearCurrentFork(\r\n taskId: string,\r\n agentId: string\r\n): Promise<void> {\r\n const key = `swarm:${taskId}:${agentId}:current-fork`;\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${key}\"`, {\r\n encoding: 'utf8'\r\n });\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to clear current fork:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Format messages for Anthropic API\r\n */\r\nexport function formatMessagesForAPI(messages: Message[]): Array<{role: string, content: string}> {\r\n return messages.map(m => ({\r\n role: m.role,\r\n content: m.content\r\n }));\r\n}\r\n\r\n/**\r\n * Get conversation statistics\r\n */\r\nexport async function getConversationStats(\r\n taskId: string,\r\n agentId: string,\r\n forkId?: string\r\n): Promise<{\r\n messageCount: number;\r\n userMessages: number;\r\n assistantMessages: number;\r\n iterations: number;\r\n firstMessage: string | null;\r\n lastMessage: string | null;\r\n}> {\r\n const messages = await loadMessages(taskId, agentId, forkId);\r\n\r\n if (messages.length === 0) {\r\n return {\r\n messageCount: 0,\r\n userMessages: 0,\r\n assistantMessages: 0,\r\n iterations: 0,\r\n firstMessage: null,\r\n lastMessage: null\r\n };\r\n }\r\n\r\n const userMessages = messages.filter(m => m.role === 'user').length;\r\n const assistantMessages = messages.filter(m => m.role === 'assistant').length;\r\n const iterations = Math.max(...messages.map(m => m.iteration));\r\n\r\n return {\r\n messageCount: messages.length,\r\n userMessages,\r\n assistantMessages,\r\n iterations,\r\n firstMessage: messages[0].timestamp,\r\n lastMessage: messages[messages.length - 1].timestamp\r\n };\r\n}\r\n"],"names":["execSync","randomBytes","redisHost","process","env","CFN_REDIS_HOST","redisPort","CFN_REDIS_PORT","storeMessage","taskId","agentId","message","key","messageJson","JSON","stringify","replace","encoding","error","console","loadMessages","forkId","output","trim","lines","split","map","line","parse","createFork","currentIteration","toString","messages","forkMessages","filter","m","iteration","length","Error","forkKey","metadata","createdAt","Date","toISOString","parentIteration","messageCount","metaKey","currentForkKey","log","getCurrentFork","getForkMetadata","metaJson","listForks","pattern","keys","k","forks","push","sort","a","b","getTime","deleteFork","messagesKey","clearCurrentFork","formatMessagesForAPI","role","content","getConversationStats","userMessages","assistantMessages","iterations","firstMessage","lastMessage","Math","max","timestamp"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/conversation-fork.ts"],"sourcesContent":["/**\r\n * Conversation Fork Management\r\n *\r\n * Implements application-level conversation forking for CFN Loop iterations.\r\n * Stores conversation history in Redis and allows branching at specific points.\r\n *\r\n * Sprint 4: Conversation Forking (v2.7.0)\r\n */\r\n\r\nimport { execSync } from 'child_process';\r\nimport { randomBytes } from 'crypto';\r\n\r\n// Bug #6 Fix: Read Redis connection parameters from process.env\r\nconst redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\nconst redisPort = process.env.CFN_REDIS_PORT || '6379';\r\n\r\nexport interface Message {\r\n role: 'user' | 'assistant';\r\n content: string;\r\n iteration: number;\r\n timestamp: string;\r\n}\r\n\r\nexport interface ForkMetadata {\r\n forkId: string;\r\n taskId: string;\r\n agentId: string;\r\n createdAt: string;\r\n parentIteration: number;\r\n messageCount: number;\r\n}\r\n\r\n/**\r\n * Store a message in conversation history\r\n * MEMORY LEAK FIX: Now sets TTL on message list to prevent indefinite accumulation\r\n */\r\nexport async function storeMessage(\r\n taskId: string,\r\n agentId: string,\r\n message: Message\r\n): Promise<void> {\r\n const key = `swarm:${taskId}:${agentId}:messages`;\r\n const messageJson = JSON.stringify(message);\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush \"${key}\" '${messageJson.replace(/'/g, \"'\\\\''\")}'`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n // MEMORY LEAK FIX: Set TTL on message list (24h default)\r\n // This prevents messages from accumulating indefinitely across multiple tasks\r\n const messageTTL = parseInt(process.env.CFN_MESSAGE_TTL || '86400', 10); // 24 hours\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire \"${key}\" ${messageTTL}`, {\r\n encoding: 'utf8'\r\n });\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to store message:`, error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Load all messages from conversation history\r\n */\r\nexport async function loadMessages(\r\n taskId: string,\r\n agentId: string,\r\n forkId?: string\r\n): Promise<Message[]> {\r\n const key = forkId\r\n ? `swarm:${taskId}:${agentId}:fork:${forkId}:messages`\r\n : `swarm:${taskId}:${agentId}:messages`;\r\n\r\n try {\r\n const output = execSync(`redis-cli -h ${redisHost} -p ${redisPort} lrange \"${key}\" 0 -1`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (!output || output === '(empty array)') {\r\n return [];\r\n }\r\n\r\n // Redis returns each message on a new line\r\n const lines = output.split('\\n');\r\n return lines.map(line => JSON.parse(line));\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to load messages:`, error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Create a fork from current conversation state\r\n * Copies all messages up to current iteration\r\n * MEMORY LEAK FIX: Now sets TTL on fork message list matching metadata TTL\r\n */\r\nexport async function createFork(\r\n taskId: string,\r\n agentId: string,\r\n currentIteration: number\r\n): Promise<string> {\r\n // Generate unique fork ID\r\n const forkId = `fork-${currentIteration}-${randomBytes(4).toString('hex')}`;\r\n\r\n // Load messages up to current iteration\r\n const messages = await loadMessages(taskId, agentId);\r\n const forkMessages = messages.filter(m => m.iteration <= currentIteration);\r\n\r\n if (forkMessages.length === 0) {\r\n throw new Error(`No messages found for iteration ${currentIteration}`);\r\n }\r\n\r\n // Store fork snapshot\r\n const forkKey = `swarm:${taskId}:${agentId}:fork:${forkId}:messages`;\r\n const forkTTL = parseInt(process.env.CFN_FORK_TTL || '86400', 10); // 24 hours\r\n\r\n for (const message of forkMessages) {\r\n const messageJson = JSON.stringify(message);\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush \"${forkKey}\" '${messageJson.replace(/'/g, \"'\\\\''\")}'`, {\r\n encoding: 'utf8'\r\n });\r\n }\r\n\r\n // MEMORY LEAK FIX: Set TTL on fork messages (was missing before)\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire \"${forkKey}\" ${forkTTL}`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n // Store fork metadata\r\n const metadata: ForkMetadata = {\r\n forkId,\r\n taskId,\r\n agentId,\r\n createdAt: new Date().toISOString(),\r\n parentIteration: currentIteration,\r\n messageCount: forkMessages.length\r\n };\r\n\r\n const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex \"${metaKey}\" ${forkTTL} '${JSON.stringify(metadata)}'`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n // Set as current fork\r\n const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex \"${currentForkKey}\" ${forkTTL} \"${forkId}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n console.log(`[conversation-fork] Created fork ${forkId} with ${forkMessages.length} messages (TTL: ${forkTTL}s)`);\r\n\r\n return forkId;\r\n}\r\n\r\n/**\r\n * Get current active fork ID\r\n */\r\nexport async function getCurrentFork(\r\n taskId: string,\r\n agentId: string\r\n): Promise<string | null> {\r\n const key = `swarm:${taskId}:${agentId}:current-fork`;\r\n\r\n try {\r\n const forkId = execSync(`redis-cli -h ${redisHost} -p ${redisPort} get \"${key}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (forkId === '(nil)' || !forkId) {\r\n return null;\r\n }\r\n\r\n return forkId;\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get fork metadata\r\n */\r\nexport async function getForkMetadata(\r\n taskId: string,\r\n agentId: string,\r\n forkId: string\r\n): Promise<ForkMetadata | null> {\r\n const key = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n\r\n try {\r\n const metaJson = execSync(`redis-cli -h ${redisHost} -p ${redisPort} get \"${key}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (metaJson === '(nil)' || !metaJson) {\r\n return null;\r\n }\r\n\r\n return JSON.parse(metaJson);\r\n } catch (error) {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * List all forks for an agent\r\n */\r\nexport async function listForks(\r\n taskId: string,\r\n agentId: string\r\n): Promise<ForkMetadata[]> {\r\n const pattern = `swarm:${taskId}:${agentId}:fork:*:meta`;\r\n\r\n try {\r\n const keys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${pattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n const forks: ForkMetadata[] = [];\r\n\r\n for (const key of keys) {\r\n const metaJson = execSync(`redis-cli -h ${redisHost} -p ${redisPort} get \"${key}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (metaJson && metaJson !== '(nil)') {\r\n forks.push(JSON.parse(metaJson));\r\n }\r\n }\r\n\r\n return forks.sort((a, b) =>\r\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\r\n );\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to list forks:`, error);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Delete a fork and its messages\r\n */\r\nexport async function deleteFork(\r\n taskId: string,\r\n agentId: string,\r\n forkId: string\r\n): Promise<void> {\r\n const messagesKey = `swarm:${taskId}:${agentId}:fork:${forkId}:messages`;\r\n const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${messagesKey}\" \"${metaKey}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n console.log(`[conversation-fork] Deleted fork ${forkId}`);\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to delete fork:`, error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Clear current fork (start fresh conversation)\r\n */\r\nexport async function clearCurrentFork(\r\n taskId: string,\r\n agentId: string\r\n): Promise<void> {\r\n const key = `swarm:${taskId}:${agentId}:current-fork`;\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${key}\"`, {\r\n encoding: 'utf8'\r\n });\r\n } catch (error) {\r\n console.error(`[conversation-fork] Failed to clear current fork:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Format messages for Anthropic API\r\n */\r\nexport function formatMessagesForAPI(messages: Message[]): Array<{role: string, content: string}> {\r\n return messages.map(m => ({\r\n role: m.role,\r\n content: m.content\r\n }));\r\n}\r\n\r\n/**\r\n * Get conversation statistics\r\n */\r\nexport async function getConversationStats(\r\n taskId: string,\r\n agentId: string,\r\n forkId?: string\r\n): Promise<{\r\n messageCount: number;\r\n userMessages: number;\r\n assistantMessages: number;\r\n iterations: number;\r\n firstMessage: string | null;\r\n lastMessage: string | null;\r\n}> {\r\n const messages = await loadMessages(taskId, agentId, forkId);\r\n\r\n if (messages.length === 0) {\r\n return {\r\n messageCount: 0,\r\n userMessages: 0,\r\n assistantMessages: 0,\r\n iterations: 0,\r\n firstMessage: null,\r\n lastMessage: null\r\n };\r\n }\r\n\r\n const userMessages = messages.filter(m => m.role === 'user').length;\r\n const assistantMessages = messages.filter(m => m.role === 'assistant').length;\r\n const iterations = Math.max(...messages.map(m => m.iteration));\r\n\r\n return {\r\n messageCount: messages.length,\r\n userMessages,\r\n assistantMessages,\r\n iterations,\r\n firstMessage: messages[0].timestamp,\r\n lastMessage: messages[messages.length - 1].timestamp\r\n };\r\n}\r\n"],"names":["execSync","randomBytes","redisHost","process","env","CFN_REDIS_HOST","redisPort","CFN_REDIS_PORT","storeMessage","taskId","agentId","message","key","messageJson","JSON","stringify","replace","encoding","messageTTL","parseInt","CFN_MESSAGE_TTL","error","console","loadMessages","forkId","output","trim","lines","split","map","line","parse","createFork","currentIteration","toString","messages","forkMessages","filter","m","iteration","length","Error","forkKey","forkTTL","CFN_FORK_TTL","metadata","createdAt","Date","toISOString","parentIteration","messageCount","metaKey","currentForkKey","log","getCurrentFork","getForkMetadata","metaJson","listForks","pattern","keys","k","forks","push","sort","a","b","getTime","deleteFork","messagesKey","clearCurrentFork","formatMessagesForAPI","role","content","getConversationStats","userMessages","assistantMessages","iterations","firstMessage","lastMessage","Math","max","timestamp"],"mappings":"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"}
|
|
@@ -139,9 +139,11 @@ const execAsync = promisify(exec);
|
|
|
139
139
|
return `Command started in background: ${command}`;
|
|
140
140
|
}
|
|
141
141
|
// Execute synchronously with timeout
|
|
142
|
+
// CRITICAL: Use /bin/bash instead of /bin/sh for [[ ]] support
|
|
142
143
|
const { stdout, stderr } = await execAsync(command, {
|
|
143
144
|
timeout: timeoutMs,
|
|
144
|
-
maxBuffer: 10 * 1024 * 1024
|
|
145
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
146
|
+
shell: '/bin/bash' // REQUIRED: Coordinator uses [[ ]] conditionals
|
|
145
147
|
});
|
|
146
148
|
return stdout + stderr;
|
|
147
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/tool-executor.ts"],"sourcesContent":["/**\r\n * Tool Executor for CLI-Spawned Agents\r\n *\r\n * Executes tools requested by agents via Anthropic API tool_use blocks.\r\n * Implements Read, Write, Edit, Bash, TodoWrite, Glob, Grep.\r\n */\r\n\r\nimport fs from 'fs/promises';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { glob } from 'glob';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\nexport interface ToolUse {\r\n type: 'tool_use';\r\n id: string;\r\n name: string;\r\n input: Record<string, any>;\r\n}\r\n\r\nexport interface ToolResult {\r\n type: 'tool_result';\r\n tool_use_id: string;\r\n content: string;\r\n is_error?: boolean;\r\n}\r\n\r\n/**\r\n * Execute a single tool and return result\r\n */\r\nexport async function executeTool(toolUse: ToolUse): Promise<ToolResult> {\r\n console.log(`[tool-executor] Executing tool: ${toolUse.name}`);\r\n console.log(`[tool-executor] Tool use ID: ${toolUse.id}`);\r\n\r\n try {\r\n let result: string;\r\n\r\n switch (toolUse.name) {\r\n case 'Read':\r\n result = await executeRead(toolUse.input);\r\n break;\r\n\r\n case 'Write':\r\n result = await executeWrite(toolUse.input);\r\n break;\r\n\r\n case 'Edit':\r\n result = await executeEdit(toolUse.input);\r\n break;\r\n\r\n case 'Bash':\r\n result = await executeBash(toolUse.input);\r\n break;\r\n\r\n case 'TodoWrite':\r\n result = await executeTodoWrite(toolUse.input);\r\n break;\r\n\r\n case 'Glob':\r\n result = await executeGlob(toolUse.input);\r\n break;\r\n\r\n case 'Grep':\r\n result = await executeGrep(toolUse.input);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown tool: ${toolUse.name}`);\r\n }\r\n\r\n console.log(`[tool-executor] ✓ Tool executed successfully`);\r\n\r\n return {\r\n type: 'tool_result',\r\n tool_use_id: toolUse.id,\r\n content: result\r\n };\r\n } catch (error) {\r\n console.error(`[tool-executor] ✗ Tool execution failed:`, error);\r\n\r\n return {\r\n type: 'tool_result',\r\n tool_use_id: toolUse.id,\r\n content: error instanceof Error ? error.message : String(error),\r\n is_error: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Execute Read tool\r\n */\r\nasync function executeRead(input: Record<string, any>): Promise<string> {\r\n const { file_path, offset, limit } = input;\r\n\r\n if (!file_path) {\r\n throw new Error('file_path parameter is required');\r\n }\r\n\r\n const content = await fs.readFile(file_path, 'utf-8');\r\n const lines = content.split('\\n');\r\n\r\n // Apply offset and limit if provided\r\n const startLine = offset ? Number(offset) - 1 : 0;\r\n const endLine = limit ? startLine + Number(limit) : lines.length;\r\n const selectedLines = lines.slice(startLine, endLine);\r\n\r\n // Format with line numbers (cat -n style)\r\n const formatted = selectedLines\r\n .map((line, idx) => `${String(startLine + idx + 1).padStart(6)}→${line}`)\r\n .join('\\n');\r\n\r\n return formatted;\r\n}\r\n\r\n/**\r\n * Execute Write tool\r\n */\r\nasync function executeWrite(input: Record<string, any>): Promise<string> {\r\n const { file_path, content } = input;\r\n\r\n if (!file_path) {\r\n throw new Error('file_path parameter is required');\r\n }\r\n\r\n if (content === undefined) {\r\n throw new Error('content parameter is required');\r\n }\r\n\r\n await fs.writeFile(file_path, content, 'utf-8');\r\n\r\n return `File written successfully: ${file_path}`;\r\n}\r\n\r\n/**\r\n * Execute Edit tool\r\n */\r\nasync function executeEdit(input: Record<string, any>): Promise<string> {\r\n const { file_path, old_string, new_string, replace_all } = input;\r\n\r\n if (!file_path) {\r\n throw new Error('file_path parameter is required');\r\n }\r\n\r\n if (!old_string) {\r\n throw new Error('old_string parameter is required');\r\n }\r\n\r\n if (new_string === undefined) {\r\n throw new Error('new_string parameter is required');\r\n }\r\n\r\n // Read file\r\n const content = await fs.readFile(file_path, 'utf-8');\r\n\r\n // Perform replacement\r\n let newContent: string;\r\n if (replace_all) {\r\n // Replace all occurrences\r\n newContent = content.split(old_string).join(new_string);\r\n } else {\r\n // Replace first occurrence only (must be unique)\r\n const occurrences = content.split(old_string).length - 1;\r\n if (occurrences === 0) {\r\n throw new Error('old_string not found in file');\r\n }\r\n if (occurrences > 1) {\r\n throw new Error(`old_string appears ${occurrences} times. Must be unique or use replace_all: true`);\r\n }\r\n newContent = content.replace(old_string, new_string);\r\n }\r\n\r\n // Write back\r\n await fs.writeFile(file_path, newContent, 'utf-8');\r\n\r\n return `File edited successfully: ${file_path}`;\r\n}\r\n\r\n/**\r\n * Execute Bash tool\r\n */\r\nasync function executeBash(input: Record<string, any>): Promise<string> {\r\n const { command, timeout, run_in_background } = input;\r\n\r\n if (!command) {\r\n throw new Error('command parameter is required');\r\n }\r\n\r\n // DEBUG: Log bash command execution details\r\n console.log(`[tool-executor] Bash command: ${command}`);\r\n console.log(`[tool-executor] Timeout: ${timeout || 120000}ms`);\r\n console.log(`[tool-executor] Background: ${run_in_background || false}`);\r\n\r\n const timeoutMs = timeout ? Number(timeout) : 120000; // 2 minutes default\r\n\r\n if (run_in_background) {\r\n // Start background process and return immediately\r\n exec(command);\r\n return `Command started in background: ${command}`;\r\n }\r\n\r\n // Execute synchronously with timeout\r\n const { stdout, stderr } = await execAsync(command, {\r\n timeout: timeoutMs,\r\n maxBuffer: 10 * 1024 * 1024 // 10MB buffer\r\n });\r\n\r\n return stdout + stderr;\r\n}\r\n\r\n/**\r\n * Execute TodoWrite tool\r\n */\r\nasync function executeTodoWrite(input: Record<string, any>): Promise<string> {\r\n const { todos } = input;\r\n\r\n if (!Array.isArray(todos)) {\r\n throw new Error('todos parameter must be an array');\r\n }\r\n\r\n // Validate todo structure\r\n for (const todo of todos) {\r\n if (!todo.content || !todo.status || !todo.activeForm) {\r\n throw new Error('Each todo must have content, status, and activeForm');\r\n }\r\n if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {\r\n throw new Error('Invalid status. Must be pending, in_progress, or completed');\r\n }\r\n }\r\n\r\n // Format todos for display\r\n const formatted = todos\r\n .map((todo, idx) => {\r\n const status = todo.status === 'completed' ? '✓' : todo.status === 'in_progress' ? '⚡' : '○';\r\n return `${idx + 1}. [${status}] ${todo.content}`;\r\n })\r\n .join('\\n');\r\n\r\n return `Todo list updated:\\n${formatted}`;\r\n}\r\n\r\n/**\r\n * Execute Glob tool\r\n */\r\nasync function executeGlob(input: Record<string, any>): Promise<string> {\r\n const { pattern, path } = input;\r\n\r\n if (!pattern) {\r\n throw new Error('pattern parameter is required');\r\n }\r\n\r\n const cwd = path || process.cwd();\r\n const files = await glob(pattern, { cwd, nodir: true });\r\n\r\n if (files.length === 0) {\r\n return 'No files found';\r\n }\r\n\r\n return files.join('\\n');\r\n}\r\n\r\n/**\r\n * Execute Grep tool\r\n */\r\nasync function executeGrep(input: Record<string, any>): Promise<string> {\r\n const { pattern, path, output_mode, glob: globPattern, type } = input;\r\n\r\n if (!pattern) {\r\n throw new Error('pattern parameter is required');\r\n }\r\n\r\n // Build ripgrep command\r\n const args: string[] = ['rg'];\r\n\r\n // Output mode\r\n if (output_mode === 'files_with_matches' || !output_mode) {\r\n args.push('-l'); // List files with matches\r\n } else if (output_mode === 'count') {\r\n args.push('-c'); // Count matches per file\r\n }\r\n // Default is content (no flag)\r\n\r\n // Optional flags\r\n if (input['-i']) args.push('-i'); // Case insensitive\r\n if (input['-n']) args.push('-n'); // Line numbers\r\n if (input['-A']) args.push(`-A${input['-A']}`); // After context\r\n if (input['-B']) args.push(`-B${input['-B']}`); // Before context\r\n if (input['-C']) args.push(`-C${input['-C']}`); // Context\r\n\r\n // File filtering\r\n if (globPattern) args.push('--glob', globPattern);\r\n if (type) args.push('--type', type);\r\n\r\n // Pattern and path\r\n args.push(pattern);\r\n if (path) args.push(path);\r\n\r\n const command = args.join(' ');\r\n\r\n try {\r\n const { stdout } = await execAsync(command, {\r\n maxBuffer: 10 * 1024 * 1024 // 10MB buffer\r\n });\r\n return stdout || 'No matches found';\r\n } catch (error: any) {\r\n // ripgrep exits with code 1 if no matches found\r\n if (error.code === 1) {\r\n return 'No matches found';\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Execute multiple tools in sequence\r\n */\r\nexport async function executeTools(toolUses: ToolUse[]): Promise<ToolResult[]> {\r\n const results: ToolResult[] = [];\r\n\r\n for (const toolUse of toolUses) {\r\n const result = await executeTool(toolUse);\r\n results.push(result);\r\n }\r\n\r\n return results;\r\n}\r\n"],"names":["fs","exec","promisify","glob","execAsync","executeTool","toolUse","console","log","name","id","result","executeRead","input","executeWrite","executeEdit","executeBash","executeTodoWrite","executeGlob","executeGrep","Error","type","tool_use_id","content","error","message","String","is_error","file_path","offset","limit","readFile","lines","split","startLine","Number","endLine","length","selectedLines","slice","formatted","map","line","idx","padStart","join","undefined","writeFile","old_string","new_string","replace_all","newContent","occurrences","replace","command","timeout","run_in_background","timeoutMs","stdout","stderr","maxBuffer","todos","Array","isArray","todo","status","activeForm","includes","pattern","path","cwd","process","files","nodir","output_mode","globPattern","args","push","code","executeTools","toolUses","results"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/tool-executor.ts"],"sourcesContent":["/**\r\n * Tool Executor for CLI-Spawned Agents\r\n *\r\n * Executes tools requested by agents via Anthropic API tool_use blocks.\r\n * Implements Read, Write, Edit, Bash, TodoWrite, Glob, Grep.\r\n */\r\n\r\nimport fs from 'fs/promises';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { glob } from 'glob';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\nexport interface ToolUse {\r\n type: 'tool_use';\r\n id: string;\r\n name: string;\r\n input: Record<string, any>;\r\n}\r\n\r\nexport interface ToolResult {\r\n type: 'tool_result';\r\n tool_use_id: string;\r\n content: string;\r\n is_error?: boolean;\r\n}\r\n\r\n/**\r\n * Execute a single tool and return result\r\n */\r\nexport async function executeTool(toolUse: ToolUse): Promise<ToolResult> {\r\n console.log(`[tool-executor] Executing tool: ${toolUse.name}`);\r\n console.log(`[tool-executor] Tool use ID: ${toolUse.id}`);\r\n\r\n try {\r\n let result: string;\r\n\r\n switch (toolUse.name) {\r\n case 'Read':\r\n result = await executeRead(toolUse.input);\r\n break;\r\n\r\n case 'Write':\r\n result = await executeWrite(toolUse.input);\r\n break;\r\n\r\n case 'Edit':\r\n result = await executeEdit(toolUse.input);\r\n break;\r\n\r\n case 'Bash':\r\n result = await executeBash(toolUse.input);\r\n break;\r\n\r\n case 'TodoWrite':\r\n result = await executeTodoWrite(toolUse.input);\r\n break;\r\n\r\n case 'Glob':\r\n result = await executeGlob(toolUse.input);\r\n break;\r\n\r\n case 'Grep':\r\n result = await executeGrep(toolUse.input);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown tool: ${toolUse.name}`);\r\n }\r\n\r\n console.log(`[tool-executor] ✓ Tool executed successfully`);\r\n\r\n return {\r\n type: 'tool_result',\r\n tool_use_id: toolUse.id,\r\n content: result\r\n };\r\n } catch (error) {\r\n console.error(`[tool-executor] ✗ Tool execution failed:`, error);\r\n\r\n return {\r\n type: 'tool_result',\r\n tool_use_id: toolUse.id,\r\n content: error instanceof Error ? error.message : String(error),\r\n is_error: true\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Execute Read tool\r\n */\r\nasync function executeRead(input: Record<string, any>): Promise<string> {\r\n const { file_path, offset, limit } = input;\r\n\r\n if (!file_path) {\r\n throw new Error('file_path parameter is required');\r\n }\r\n\r\n const content = await fs.readFile(file_path, 'utf-8');\r\n const lines = content.split('\\n');\r\n\r\n // Apply offset and limit if provided\r\n const startLine = offset ? Number(offset) - 1 : 0;\r\n const endLine = limit ? startLine + Number(limit) : lines.length;\r\n const selectedLines = lines.slice(startLine, endLine);\r\n\r\n // Format with line numbers (cat -n style)\r\n const formatted = selectedLines\r\n .map((line, idx) => `${String(startLine + idx + 1).padStart(6)}→${line}`)\r\n .join('\\n');\r\n\r\n return formatted;\r\n}\r\n\r\n/**\r\n * Execute Write tool\r\n */\r\nasync function executeWrite(input: Record<string, any>): Promise<string> {\r\n const { file_path, content } = input;\r\n\r\n if (!file_path) {\r\n throw new Error('file_path parameter is required');\r\n }\r\n\r\n if (content === undefined) {\r\n throw new Error('content parameter is required');\r\n }\r\n\r\n await fs.writeFile(file_path, content, 'utf-8');\r\n\r\n return `File written successfully: ${file_path}`;\r\n}\r\n\r\n/**\r\n * Execute Edit tool\r\n */\r\nasync function executeEdit(input: Record<string, any>): Promise<string> {\r\n const { file_path, old_string, new_string, replace_all } = input;\r\n\r\n if (!file_path) {\r\n throw new Error('file_path parameter is required');\r\n }\r\n\r\n if (!old_string) {\r\n throw new Error('old_string parameter is required');\r\n }\r\n\r\n if (new_string === undefined) {\r\n throw new Error('new_string parameter is required');\r\n }\r\n\r\n // Read file\r\n const content = await fs.readFile(file_path, 'utf-8');\r\n\r\n // Perform replacement\r\n let newContent: string;\r\n if (replace_all) {\r\n // Replace all occurrences\r\n newContent = content.split(old_string).join(new_string);\r\n } else {\r\n // Replace first occurrence only (must be unique)\r\n const occurrences = content.split(old_string).length - 1;\r\n if (occurrences === 0) {\r\n throw new Error('old_string not found in file');\r\n }\r\n if (occurrences > 1) {\r\n throw new Error(`old_string appears ${occurrences} times. Must be unique or use replace_all: true`);\r\n }\r\n newContent = content.replace(old_string, new_string);\r\n }\r\n\r\n // Write back\r\n await fs.writeFile(file_path, newContent, 'utf-8');\r\n\r\n return `File edited successfully: ${file_path}`;\r\n}\r\n\r\n/**\r\n * Execute Bash tool\r\n */\r\nasync function executeBash(input: Record<string, any>): Promise<string> {\r\n const { command, timeout, run_in_background } = input;\r\n\r\n if (!command) {\r\n throw new Error('command parameter is required');\r\n }\r\n\r\n // DEBUG: Log bash command execution details\r\n console.log(`[tool-executor] Bash command: ${command}`);\r\n console.log(`[tool-executor] Timeout: ${timeout || 120000}ms`);\r\n console.log(`[tool-executor] Background: ${run_in_background || false}`);\r\n\r\n const timeoutMs = timeout ? Number(timeout) : 120000; // 2 minutes default\r\n\r\n if (run_in_background) {\r\n // Start background process and return immediately\r\n exec(command);\r\n return `Command started in background: ${command}`;\r\n }\r\n\r\n // Execute synchronously with timeout\r\n // CRITICAL: Use /bin/bash instead of /bin/sh for [[ ]] support\r\n const { stdout, stderr } = await execAsync(command, {\r\n timeout: timeoutMs,\r\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\r\n shell: '/bin/bash' // REQUIRED: Coordinator uses [[ ]] conditionals\r\n });\r\n\r\n return stdout + stderr;\r\n}\r\n\r\n/**\r\n * Execute TodoWrite tool\r\n */\r\nasync function executeTodoWrite(input: Record<string, any>): Promise<string> {\r\n const { todos } = input;\r\n\r\n if (!Array.isArray(todos)) {\r\n throw new Error('todos parameter must be an array');\r\n }\r\n\r\n // Validate todo structure\r\n for (const todo of todos) {\r\n if (!todo.content || !todo.status || !todo.activeForm) {\r\n throw new Error('Each todo must have content, status, and activeForm');\r\n }\r\n if (!['pending', 'in_progress', 'completed'].includes(todo.status)) {\r\n throw new Error('Invalid status. Must be pending, in_progress, or completed');\r\n }\r\n }\r\n\r\n // Format todos for display\r\n const formatted = todos\r\n .map((todo, idx) => {\r\n const status = todo.status === 'completed' ? '✓' : todo.status === 'in_progress' ? '⚡' : '○';\r\n return `${idx + 1}. [${status}] ${todo.content}`;\r\n })\r\n .join('\\n');\r\n\r\n return `Todo list updated:\\n${formatted}`;\r\n}\r\n\r\n/**\r\n * Execute Glob tool\r\n */\r\nasync function executeGlob(input: Record<string, any>): Promise<string> {\r\n const { pattern, path } = input;\r\n\r\n if (!pattern) {\r\n throw new Error('pattern parameter is required');\r\n }\r\n\r\n const cwd = path || process.cwd();\r\n const files = await glob(pattern, { cwd, nodir: true });\r\n\r\n if (files.length === 0) {\r\n return 'No files found';\r\n }\r\n\r\n return files.join('\\n');\r\n}\r\n\r\n/**\r\n * Execute Grep tool\r\n */\r\nasync function executeGrep(input: Record<string, any>): Promise<string> {\r\n const { pattern, path, output_mode, glob: globPattern, type } = input;\r\n\r\n if (!pattern) {\r\n throw new Error('pattern parameter is required');\r\n }\r\n\r\n // Build ripgrep command\r\n const args: string[] = ['rg'];\r\n\r\n // Output mode\r\n if (output_mode === 'files_with_matches' || !output_mode) {\r\n args.push('-l'); // List files with matches\r\n } else if (output_mode === 'count') {\r\n args.push('-c'); // Count matches per file\r\n }\r\n // Default is content (no flag)\r\n\r\n // Optional flags\r\n if (input['-i']) args.push('-i'); // Case insensitive\r\n if (input['-n']) args.push('-n'); // Line numbers\r\n if (input['-A']) args.push(`-A${input['-A']}`); // After context\r\n if (input['-B']) args.push(`-B${input['-B']}`); // Before context\r\n if (input['-C']) args.push(`-C${input['-C']}`); // Context\r\n\r\n // File filtering\r\n if (globPattern) args.push('--glob', globPattern);\r\n if (type) args.push('--type', type);\r\n\r\n // Pattern and path\r\n args.push(pattern);\r\n if (path) args.push(path);\r\n\r\n const command = args.join(' ');\r\n\r\n try {\r\n const { stdout } = await execAsync(command, {\r\n maxBuffer: 10 * 1024 * 1024 // 10MB buffer\r\n });\r\n return stdout || 'No matches found';\r\n } catch (error: any) {\r\n // ripgrep exits with code 1 if no matches found\r\n if (error.code === 1) {\r\n return 'No matches found';\r\n }\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Execute multiple tools in sequence\r\n */\r\nexport async function executeTools(toolUses: ToolUse[]): Promise<ToolResult[]> {\r\n const results: ToolResult[] = [];\r\n\r\n for (const toolUse of toolUses) {\r\n const result = await executeTool(toolUse);\r\n results.push(result);\r\n }\r\n\r\n return results;\r\n}\r\n"],"names":["fs","exec","promisify","glob","execAsync","executeTool","toolUse","console","log","name","id","result","executeRead","input","executeWrite","executeEdit","executeBash","executeTodoWrite","executeGlob","executeGrep","Error","type","tool_use_id","content","error","message","String","is_error","file_path","offset","limit","readFile","lines","split","startLine","Number","endLine","length","selectedLines","slice","formatted","map","line","idx","padStart","join","undefined","writeFile","old_string","new_string","replace_all","newContent","occurrences","replace","command","timeout","run_in_background","timeoutMs","stdout","stderr","maxBuffer","shell","todos","Array","isArray","todo","status","activeForm","includes","pattern","path","cwd","process","files","nodir","output_mode","globPattern","args","push","code","executeTools","toolUses","results"],"mappings":"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"}
|