@winspan/claude-forge 0.1.1
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/LICENSE +21 -0
- package/README.md +505 -0
- package/dist/autopilot/index.d.ts +4 -0
- package/dist/autopilot/index.d.ts.map +1 -0
- package/dist/autopilot/index.js +4 -0
- package/dist/autopilot/index.js.map +1 -0
- package/dist/autopilot/intent-engine.d.ts +60 -0
- package/dist/autopilot/intent-engine.d.ts.map +1 -0
- package/dist/autopilot/intent-engine.js +308 -0
- package/dist/autopilot/intent-engine.js.map +1 -0
- package/dist/autopilot/knowledge-engine.d.ts +67 -0
- package/dist/autopilot/knowledge-engine.d.ts.map +1 -0
- package/dist/autopilot/knowledge-engine.js +262 -0
- package/dist/autopilot/knowledge-engine.js.map +1 -0
- package/dist/autopilot/quality-gate.d.ts +69 -0
- package/dist/autopilot/quality-gate.d.ts.map +1 -0
- package/dist/autopilot/quality-gate.js +244 -0
- package/dist/autopilot/quality-gate.js.map +1 -0
- package/dist/autopilot/team-orchestrator.d.ts +16 -0
- package/dist/autopilot/team-orchestrator.d.ts.map +1 -0
- package/dist/autopilot/team-orchestrator.js +56 -0
- package/dist/autopilot/team-orchestrator.js.map +1 -0
- package/dist/backup/index.d.ts +16 -0
- package/dist/backup/index.d.ts.map +1 -0
- package/dist/backup/index.js +169 -0
- package/dist/backup/index.js.map +1 -0
- package/dist/claudemd/detector.d.ts +54 -0
- package/dist/claudemd/detector.d.ts.map +1 -0
- package/dist/claudemd/detector.js +510 -0
- package/dist/claudemd/detector.js.map +1 -0
- package/dist/claudemd/index.d.ts +44 -0
- package/dist/claudemd/index.d.ts.map +1 -0
- package/dist/claudemd/index.js +193 -0
- package/dist/claudemd/index.js.map +1 -0
- package/dist/claudemd/modules-config.d.ts +37 -0
- package/dist/claudemd/modules-config.d.ts.map +1 -0
- package/dist/claudemd/modules-config.js +80 -0
- package/dist/claudemd/modules-config.js.map +1 -0
- package/dist/claudemd/prompt-injector.d.ts +29 -0
- package/dist/claudemd/prompt-injector.d.ts.map +1 -0
- package/dist/claudemd/prompt-injector.js +144 -0
- package/dist/claudemd/prompt-injector.js.map +1 -0
- package/dist/claudemd/prompts.d.ts +16 -0
- package/dist/claudemd/prompts.d.ts.map +1 -0
- package/dist/claudemd/prompts.js +439 -0
- package/dist/claudemd/prompts.js.map +1 -0
- package/dist/claudemd/writer.d.ts +27 -0
- package/dist/claudemd/writer.d.ts.map +1 -0
- package/dist/claudemd/writer.js +91 -0
- package/dist/claudemd/writer.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +3 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +63 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/claudemd.d.ts +3 -0
- package/dist/cli/commands/claudemd.d.ts.map +1 -0
- package/dist/cli/commands/claudemd.js +322 -0
- package/dist/cli/commands/claudemd.js.map +1 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +67 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/console.d.ts +3 -0
- package/dist/cli/commands/console.d.ts.map +1 -0
- package/dist/cli/commands/console.js +11 -0
- package/dist/cli/commands/console.js.map +1 -0
- package/dist/cli/commands/convention.d.ts +3 -0
- package/dist/cli/commands/convention.d.ts.map +1 -0
- package/dist/cli/commands/convention.js +269 -0
- package/dist/cli/commands/convention.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +3 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +191 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/distill.d.ts +3 -0
- package/dist/cli/commands/distill.d.ts.map +1 -0
- package/dist/cli/commands/distill.js +61 -0
- package/dist/cli/commands/distill.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +306 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +3 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +311 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/pattern.d.ts +3 -0
- package/dist/cli/commands/pattern.d.ts.map +1 -0
- package/dist/cli/commands/pattern.js +118 -0
- package/dist/cli/commands/pattern.js.map +1 -0
- package/dist/cli/commands/pipeline.d.ts +3 -0
- package/dist/cli/commands/pipeline.d.ts.map +1 -0
- package/dist/cli/commands/pipeline.js +75 -0
- package/dist/cli/commands/pipeline.js.map +1 -0
- package/dist/cli/commands/profile.d.ts +3 -0
- package/dist/cli/commands/profile.d.ts.map +1 -0
- package/dist/cli/commands/profile.js +213 -0
- package/dist/cli/commands/profile.js.map +1 -0
- package/dist/cli/commands/query.d.ts +3 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +115 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +3 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +466 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +49 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/interceptor.d.ts +5 -0
- package/dist/cli/interceptor.d.ts.map +1 -0
- package/dist/cli/interceptor.js +55 -0
- package/dist/cli/interceptor.js.map +1 -0
- package/dist/cli/tui.d.ts +2 -0
- package/dist/cli/tui.d.ts.map +1 -0
- package/dist/cli/tui.js +360 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/cli/utils/errors.d.ts +17 -0
- package/dist/cli/utils/errors.d.ts.map +1 -0
- package/dist/cli/utils/errors.js +42 -0
- package/dist/cli/utils/errors.js.map +1 -0
- package/dist/cli/utils/output.d.ts +23 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +69 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +50 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +26 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +161 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +59 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +86 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/convention/convention-distiller.d.ts +28 -0
- package/dist/convention/convention-distiller.d.ts.map +1 -0
- package/dist/convention/convention-distiller.js +172 -0
- package/dist/convention/convention-distiller.js.map +1 -0
- package/dist/convention/convention-evolver.d.ts +31 -0
- package/dist/convention/convention-evolver.d.ts.map +1 -0
- package/dist/convention/convention-evolver.js +175 -0
- package/dist/convention/convention-evolver.js.map +1 -0
- package/dist/convention/convention-loader.d.ts +22 -0
- package/dist/convention/convention-loader.d.ts.map +1 -0
- package/dist/convention/convention-loader.js +139 -0
- package/dist/convention/convention-loader.js.map +1 -0
- package/dist/convention/convention-manager.d.ts +46 -0
- package/dist/convention/convention-manager.d.ts.map +1 -0
- package/dist/convention/convention-manager.js +193 -0
- package/dist/convention/convention-manager.js.map +1 -0
- package/dist/convention/index.d.ts +6 -0
- package/dist/convention/index.d.ts.map +1 -0
- package/dist/convention/index.js +5 -0
- package/dist/convention/index.js.map +1 -0
- package/dist/convention/types.d.ts +90 -0
- package/dist/convention/types.d.ts.map +1 -0
- package/dist/convention/types.js +13 -0
- package/dist/convention/types.js.map +1 -0
- package/dist/daemon/engine-registry/init-autopilot.d.ts +12 -0
- package/dist/daemon/engine-registry/init-autopilot.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-autopilot.js +20 -0
- package/dist/daemon/engine-registry/init-autopilot.js.map +1 -0
- package/dist/daemon/engine-registry/init-distill.d.ts +6 -0
- package/dist/daemon/engine-registry/init-distill.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-distill.js +25 -0
- package/dist/daemon/engine-registry/init-distill.js.map +1 -0
- package/dist/daemon/engine-registry/init-orchestration.d.ts +5 -0
- package/dist/daemon/engine-registry/init-orchestration.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-orchestration.js +11 -0
- package/dist/daemon/engine-registry/init-orchestration.js.map +1 -0
- package/dist/daemon/engine-registry/init-pattern-engine.d.ts +9 -0
- package/dist/daemon/engine-registry/init-pattern-engine.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-pattern-engine.js +22 -0
- package/dist/daemon/engine-registry/init-pattern-engine.js.map +1 -0
- package/dist/daemon/engine-registry/init-pipeline.d.ts +5 -0
- package/dist/daemon/engine-registry/init-pipeline.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-pipeline.js +12 -0
- package/dist/daemon/engine-registry/init-pipeline.js.map +1 -0
- package/dist/daemon/engine-registry/init-profile.d.ts +3 -0
- package/dist/daemon/engine-registry/init-profile.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-profile.js +28 -0
- package/dist/daemon/engine-registry/init-profile.js.map +1 -0
- package/dist/daemon/engine-registry/init-resume.d.ts +6 -0
- package/dist/daemon/engine-registry/init-resume.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-resume.js +16 -0
- package/dist/daemon/engine-registry/init-resume.js.map +1 -0
- package/dist/daemon/engine-registry/init-skill-registry.d.ts +10 -0
- package/dist/daemon/engine-registry/init-skill-registry.d.ts.map +1 -0
- package/dist/daemon/engine-registry/init-skill-registry.js +46 -0
- package/dist/daemon/engine-registry/init-skill-registry.js.map +1 -0
- package/dist/daemon/engine-registry.d.ts +13 -0
- package/dist/daemon/engine-registry.d.ts.map +1 -0
- package/dist/daemon/engine-registry.js +45 -0
- package/dist/daemon/engine-registry.js.map +1 -0
- package/dist/daemon/event-parser.d.ts +5 -0
- package/dist/daemon/event-parser.d.ts.map +1 -0
- package/dist/daemon/event-parser.js +29 -0
- package/dist/daemon/event-parser.js.map +1 -0
- package/dist/daemon/handler-context.d.ts +37 -0
- package/dist/daemon/handler-context.d.ts.map +1 -0
- package/dist/daemon/handler-context.js +2 -0
- package/dist/daemon/handler-context.js.map +1 -0
- package/dist/daemon/handlers/base-handler.d.ts +14 -0
- package/dist/daemon/handlers/base-handler.d.ts.map +1 -0
- package/dist/daemon/handlers/base-handler.js +18 -0
- package/dist/daemon/handlers/base-handler.js.map +1 -0
- package/dist/daemon/handlers/conversational-config-handler.d.ts +24 -0
- package/dist/daemon/handlers/conversational-config-handler.d.ts.map +1 -0
- package/dist/daemon/handlers/conversational-config-handler.js +175 -0
- package/dist/daemon/handlers/conversational-config-handler.js.map +1 -0
- package/dist/daemon/handlers/post-tool-use-handler.d.ts +9 -0
- package/dist/daemon/handlers/post-tool-use-handler.d.ts.map +1 -0
- package/dist/daemon/handlers/post-tool-use-handler.js +82 -0
- package/dist/daemon/handlers/post-tool-use-handler.js.map +1 -0
- package/dist/daemon/handlers/pre-tool-use-handler.d.ts +11 -0
- package/dist/daemon/handlers/pre-tool-use-handler.d.ts.map +1 -0
- package/dist/daemon/handlers/pre-tool-use-handler.js +58 -0
- package/dist/daemon/handlers/pre-tool-use-handler.js.map +1 -0
- package/dist/daemon/handlers/stop-handler.d.ts +11 -0
- package/dist/daemon/handlers/stop-handler.d.ts.map +1 -0
- package/dist/daemon/handlers/stop-handler.js +112 -0
- package/dist/daemon/handlers/stop-handler.js.map +1 -0
- package/dist/daemon/handlers/user-prompt-handler.d.ts +72 -0
- package/dist/daemon/handlers/user-prompt-handler.d.ts.map +1 -0
- package/dist/daemon/handlers/user-prompt-handler.js +374 -0
- package/dist/daemon/handlers/user-prompt-handler.js.map +1 -0
- package/dist/daemon/index.d.ts +2 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +284 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +9 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +56 -0
- package/dist/daemon/lifecycle.js.map +1 -0
- package/dist/daemon/server.d.ts +22 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +139 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/distill/index.d.ts +16 -0
- package/dist/distill/index.d.ts.map +1 -0
- package/dist/distill/index.js +104 -0
- package/dist/distill/index.js.map +1 -0
- package/dist/distill/prompts.d.ts +6 -0
- package/dist/distill/prompts.d.ts.map +1 -0
- package/dist/distill/prompts.js +77 -0
- package/dist/distill/prompts.js.map +1 -0
- package/dist/distill/trigger.d.ts +40 -0
- package/dist/distill/trigger.d.ts.map +1 -0
- package/dist/distill/trigger.js +127 -0
- package/dist/distill/trigger.js.map +1 -0
- package/dist/distill/writer.d.ts +15 -0
- package/dist/distill/writer.d.ts.map +1 -0
- package/dist/distill/writer.js +73 -0
- package/dist/distill/writer.js.map +1 -0
- package/dist/doc-sync/index.d.ts +21 -0
- package/dist/doc-sync/index.d.ts.map +1 -0
- package/dist/doc-sync/index.js +190 -0
- package/dist/doc-sync/index.js.map +1 -0
- package/dist/hooks/check-context-limit.sh +97 -0
- package/dist/hooks/hooks/check-context-limit.sh +97 -0
- package/dist/hooks/hooks/notification.sh +33 -0
- package/dist/hooks/hooks/post-tool-use.sh +49 -0
- package/dist/hooks/hooks/pre-tool-use.sh +55 -0
- package/dist/hooks/hooks/stop.sh +29 -0
- package/dist/hooks/hooks/user-prompt-submit.sh +72 -0
- package/dist/hooks/notification.sh +33 -0
- package/dist/hooks/post-tool-use.sh +49 -0
- package/dist/hooks/pre-tool-use.sh +55 -0
- package/dist/hooks/stop.sh +29 -0
- package/dist/hooks/user-prompt-submit.sh +72 -0
- package/dist/orchestration/index.d.ts +32 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +72 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/notifier.d.ts +11 -0
- package/dist/orchestration/notifier.d.ts.map +1 -0
- package/dist/orchestration/notifier.js +22 -0
- package/dist/orchestration/notifier.js.map +1 -0
- package/dist/orchestration/policy-engine.d.ts +21 -0
- package/dist/orchestration/policy-engine.d.ts.map +1 -0
- package/dist/orchestration/policy-engine.js +77 -0
- package/dist/orchestration/policy-engine.js.map +1 -0
- package/dist/orchestration/tracker.d.ts +45 -0
- package/dist/orchestration/tracker.d.ts.map +1 -0
- package/dist/orchestration/tracker.js +95 -0
- package/dist/orchestration/tracker.js.map +1 -0
- package/dist/pattern-engine/execution-tracker.d.ts +45 -0
- package/dist/pattern-engine/execution-tracker.d.ts.map +1 -0
- package/dist/pattern-engine/execution-tracker.js +132 -0
- package/dist/pattern-engine/execution-tracker.js.map +1 -0
- package/dist/pattern-engine/index.d.ts +52 -0
- package/dist/pattern-engine/index.d.ts.map +1 -0
- package/dist/pattern-engine/index.js +104 -0
- package/dist/pattern-engine/index.js.map +1 -0
- package/dist/pattern-engine/pattern-evolver.d.ts +39 -0
- package/dist/pattern-engine/pattern-evolver.d.ts.map +1 -0
- package/dist/pattern-engine/pattern-evolver.js +170 -0
- package/dist/pattern-engine/pattern-evolver.js.map +1 -0
- package/dist/pattern-engine/pattern-executor.d.ts +43 -0
- package/dist/pattern-engine/pattern-executor.d.ts.map +1 -0
- package/dist/pattern-engine/pattern-executor.js +185 -0
- package/dist/pattern-engine/pattern-executor.js.map +1 -0
- package/dist/pattern-engine/pattern-loader.d.ts +14 -0
- package/dist/pattern-engine/pattern-loader.d.ts.map +1 -0
- package/dist/pattern-engine/pattern-loader.js +111 -0
- package/dist/pattern-engine/pattern-loader.js.map +1 -0
- package/dist/pattern-engine/pattern-router.d.ts +24 -0
- package/dist/pattern-engine/pattern-router.d.ts.map +1 -0
- package/dist/pattern-engine/pattern-router.js +124 -0
- package/dist/pattern-engine/pattern-router.js.map +1 -0
- package/dist/pattern-engine/types.d.ts +144 -0
- package/dist/pattern-engine/types.d.ts.map +1 -0
- package/dist/pattern-engine/types.js +8 -0
- package/dist/pattern-engine/types.js.map +1 -0
- package/dist/pipeline/analyzer.d.ts +17 -0
- package/dist/pipeline/analyzer.d.ts.map +1 -0
- package/dist/pipeline/analyzer.js +103 -0
- package/dist/pipeline/analyzer.js.map +1 -0
- package/dist/pipeline/index.d.ts +68 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +183 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/phase-manager.d.ts +32 -0
- package/dist/pipeline/phase-manager.d.ts.map +1 -0
- package/dist/pipeline/phase-manager.js +188 -0
- package/dist/pipeline/phase-manager.js.map +1 -0
- package/dist/pipeline/pipeline-options.d.ts +19 -0
- package/dist/pipeline/pipeline-options.d.ts.map +1 -0
- package/dist/pipeline/pipeline-options.js +136 -0
- package/dist/pipeline/pipeline-options.js.map +1 -0
- package/dist/pipeline/store.d.ts +32 -0
- package/dist/pipeline/store.d.ts.map +1 -0
- package/dist/pipeline/store.js +113 -0
- package/dist/pipeline/store.js.map +1 -0
- package/dist/pipeline/types.d.ts +25 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +16 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/profile/index.d.ts +77 -0
- package/dist/profile/index.d.ts.map +1 -0
- package/dist/profile/index.js +407 -0
- package/dist/profile/index.js.map +1 -0
- package/dist/resume/context-gen.d.ts +20 -0
- package/dist/resume/context-gen.d.ts.map +1 -0
- package/dist/resume/context-gen.js +130 -0
- package/dist/resume/context-gen.js.map +1 -0
- package/dist/resume/index.d.ts +32 -0
- package/dist/resume/index.d.ts.map +1 -0
- package/dist/resume/index.js +142 -0
- package/dist/resume/index.js.map +1 -0
- package/dist/resume/state-machine.d.ts +21 -0
- package/dist/resume/state-machine.d.ts.map +1 -0
- package/dist/resume/state-machine.js +58 -0
- package/dist/resume/state-machine.js.map +1 -0
- package/dist/skill-registry/collector.d.ts +75 -0
- package/dist/skill-registry/collector.d.ts.map +1 -0
- package/dist/skill-registry/collector.js +334 -0
- package/dist/skill-registry/collector.js.map +1 -0
- package/dist/skill-registry/evolver.d.ts +84 -0
- package/dist/skill-registry/evolver.d.ts.map +1 -0
- package/dist/skill-registry/evolver.js +585 -0
- package/dist/skill-registry/evolver.js.map +1 -0
- package/dist/skill-registry/index.d.ts +73 -0
- package/dist/skill-registry/index.d.ts.map +1 -0
- package/dist/skill-registry/index.js +195 -0
- package/dist/skill-registry/index.js.map +1 -0
- package/dist/skill-registry/official-sync.d.ts +20 -0
- package/dist/skill-registry/official-sync.d.ts.map +1 -0
- package/dist/skill-registry/official-sync.js +576 -0
- package/dist/skill-registry/official-sync.js.map +1 -0
- package/dist/skill-registry/orchestration-config.d.ts +35 -0
- package/dist/skill-registry/orchestration-config.d.ts.map +1 -0
- package/dist/skill-registry/orchestration-config.js +125 -0
- package/dist/skill-registry/orchestration-config.js.map +1 -0
- package/dist/skill-registry/orchestrator.d.ts +45 -0
- package/dist/skill-registry/orchestrator.d.ts.map +1 -0
- package/dist/skill-registry/orchestrator.js +183 -0
- package/dist/skill-registry/orchestrator.js.map +1 -0
- package/dist/skill-registry/project-learner.d.ts +25 -0
- package/dist/skill-registry/project-learner.d.ts.map +1 -0
- package/dist/skill-registry/project-learner.js +176 -0
- package/dist/skill-registry/project-learner.js.map +1 -0
- package/dist/skill-registry/recommender.d.ts +25 -0
- package/dist/skill-registry/recommender.d.ts.map +1 -0
- package/dist/skill-registry/recommender.js +91 -0
- package/dist/skill-registry/recommender.js.map +1 -0
- package/dist/skill-registry/registry.d.ts +49 -0
- package/dist/skill-registry/registry.d.ts.map +1 -0
- package/dist/skill-registry/registry.js +160 -0
- package/dist/skill-registry/registry.js.map +1 -0
- package/dist/skill-registry/scanner.d.ts +36 -0
- package/dist/skill-registry/scanner.d.ts.map +1 -0
- package/dist/skill-registry/scanner.js +122 -0
- package/dist/skill-registry/scanner.js.map +1 -0
- package/dist/skill-registry/skills-config.d.ts +29 -0
- package/dist/skill-registry/skills-config.d.ts.map +1 -0
- package/dist/skill-registry/skills-config.js +86 -0
- package/dist/skill-registry/skills-config.js.map +1 -0
- package/dist/storage/index.d.ts +31 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/sqlite.d.ts +58 -0
- package/dist/storage/sqlite.d.ts.map +1 -0
- package/dist/storage/sqlite.js +375 -0
- package/dist/storage/sqlite.js.map +1 -0
- package/dist/tests/claude-api.test.d.ts +2 -0
- package/dist/tests/claude-api.test.d.ts.map +1 -0
- package/dist/tests/claude-api.test.js +96 -0
- package/dist/tests/claude-api.test.js.map +1 -0
- package/dist/tests/conversational-config-handler.test.d.ts +2 -0
- package/dist/tests/conversational-config-handler.test.d.ts.map +1 -0
- package/dist/tests/conversational-config-handler.test.js +107 -0
- package/dist/tests/conversational-config-handler.test.js.map +1 -0
- package/dist/tests/doc-sync.test.d.ts +2 -0
- package/dist/tests/doc-sync.test.d.ts.map +1 -0
- package/dist/tests/doc-sync.test.js +148 -0
- package/dist/tests/doc-sync.test.js.map +1 -0
- package/dist/tests/orchestration-config.test.d.ts +2 -0
- package/dist/tests/orchestration-config.test.d.ts.map +1 -0
- package/dist/tests/orchestration-config.test.js +122 -0
- package/dist/tests/orchestration-config.test.js.map +1 -0
- package/dist/tests/pipeline-options.test.d.ts +2 -0
- package/dist/tests/pipeline-options.test.d.ts.map +1 -0
- package/dist/tests/pipeline-options.test.js +68 -0
- package/dist/tests/pipeline-options.test.js.map +1 -0
- package/dist/tests/resume-context-gen.test.d.ts +2 -0
- package/dist/tests/resume-context-gen.test.d.ts.map +1 -0
- package/dist/tests/resume-context-gen.test.js +93 -0
- package/dist/tests/resume-context-gen.test.js.map +1 -0
- package/dist/tests/sqlite.test.d.ts +2 -0
- package/dist/tests/sqlite.test.d.ts.map +1 -0
- package/dist/tests/sqlite.test.js +154 -0
- package/dist/tests/sqlite.test.js.map +1 -0
- package/dist/tests/tracker.test.d.ts +2 -0
- package/dist/tests/tracker.test.d.ts.map +1 -0
- package/dist/tests/tracker.test.js +75 -0
- package/dist/tests/tracker.test.js.map +1 -0
- package/dist/tests/tui.test.d.ts +2 -0
- package/dist/tests/tui.test.d.ts.map +1 -0
- package/dist/tests/tui.test.js +39 -0
- package/dist/tests/tui.test.js.map +1 -0
- package/dist/tests/user-prompt-handler.test.d.ts +2 -0
- package/dist/tests/user-prompt-handler.test.d.ts.map +1 -0
- package/dist/tests/user-prompt-handler.test.js +182 -0
- package/dist/tests/user-prompt-handler.test.js.map +1 -0
- package/dist/tui/index.d.ts +2 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +486 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/types/event.d.ts +24 -0
- package/dist/types/event.d.ts.map +1 -0
- package/dist/types/event.js +2 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/session.d.ts +11 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +2 -0
- package/dist/types/session.js.map +1 -0
- package/dist/utils/claude-api.d.ts +49 -0
- package/dist/utils/claude-api.d.ts.map +1 -0
- package/dist/utils/claude-api.js +233 -0
- package/dist/utils/claude-api.js.map +1 -0
- package/dist/utils/formatter.d.ts +57 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +109 -0
- package/dist/utils/formatter.js.map +1 -0
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +136 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mutex-lock.d.ts +23 -0
- package/dist/utils/mutex-lock.d.ts.map +1 -0
- package/dist/utils/mutex-lock.js +42 -0
- package/dist/utils/mutex-lock.js.map +1 -0
- package/dist/utils/truncate.d.ts +30 -0
- package/dist/utils/truncate.d.ts.map +1 -0
- package/dist/utils/truncate.js +64 -0
- package/dist/utils/truncate.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Claude Forge - PostToolUse Hook
|
|
3
|
+
|
|
4
|
+
SOCKET_PATH="${CLAUDE_FORGE_SOCKET:-$HOME/.claude-forge/daemon.sock}"
|
|
5
|
+
|
|
6
|
+
# 读取 stdin
|
|
7
|
+
INPUT=$(cat)
|
|
8
|
+
|
|
9
|
+
# 提取字段(tool_response 是 Claude Code 的字段名)
|
|
10
|
+
TOOL_NAME="${CLAUDE_TOOL_NAME:-$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_name",""))' 2>/dev/null || echo '')}"
|
|
11
|
+
TOOL_INPUT=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get("tool_input",{})))' 2>/dev/null || echo '{}')
|
|
12
|
+
TOOL_OUTPUT=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get("tool_response",{})))' 2>/dev/null || echo '{}')
|
|
13
|
+
# cwd 是 Claude Code 的项目根目录
|
|
14
|
+
PROJECT_PATH=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("cwd",""))' 2>/dev/null || echo '')
|
|
15
|
+
PROJECT_PATH="${PROJECT_PATH:-${PWD}}"
|
|
16
|
+
|
|
17
|
+
# 构造事件 JSON(通过环境变量传参,避免 shell 注入)
|
|
18
|
+
EVENT=$(FORGE_TOOL_NAME="$TOOL_NAME" FORGE_TOOL_INPUT="$TOOL_INPUT" FORGE_TOOL_OUTPUT="$TOOL_OUTPUT" FORGE_PROJECT_PATH="$PROJECT_PATH" \
|
|
19
|
+
python3 -c "
|
|
20
|
+
import json, os
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
try:
|
|
23
|
+
tool_input = json.loads(os.environ.get('FORGE_TOOL_INPUT', '{}'))
|
|
24
|
+
except Exception:
|
|
25
|
+
tool_input = {}
|
|
26
|
+
try:
|
|
27
|
+
tool_output = json.loads(os.environ.get('FORGE_TOOL_OUTPUT', '{}'))
|
|
28
|
+
except Exception:
|
|
29
|
+
tool_output = {}
|
|
30
|
+
print(json.dumps({
|
|
31
|
+
'hook_type': 'PostToolUse',
|
|
32
|
+
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S'),
|
|
33
|
+
'session_id': os.environ.get('CLAUDE_CODE_SESSION_ID', 'cli'),
|
|
34
|
+
'project_path': os.environ.get('FORGE_PROJECT_PATH', ''),
|
|
35
|
+
'tool_name': os.environ.get('FORGE_TOOL_NAME', ''),
|
|
36
|
+
'tool_input': tool_input,
|
|
37
|
+
'tool_output': tool_output,
|
|
38
|
+
}))
|
|
39
|
+
" 2>/dev/null)
|
|
40
|
+
|
|
41
|
+
# 发送到 daemon(PostToolUse 也需要等待响应以支持通知注入)
|
|
42
|
+
RESPONSE=$(echo "$EVENT" | nc -U -w 5 "$SOCKET_PATH" 2>/dev/null || true)
|
|
43
|
+
if [ -n "$RESPONSE" ]; then
|
|
44
|
+
HAS_CONTEXT=$(echo "$RESPONSE" | python3 -c 'import sys,json; d=json.load(sys.stdin); print("yes" if d.get("additionalContext") else "no")' 2>/dev/null || echo 'no')
|
|
45
|
+
if [ "$HAS_CONTEXT" = "yes" ]; then
|
|
46
|
+
echo "$RESPONSE"
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
exit 0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Claude Forge - PreToolUse Hook(双向通信)
|
|
3
|
+
|
|
4
|
+
SOCKET_PATH="${CLAUDE_FORGE_SOCKET:-$HOME/.claude-forge/daemon.sock}"
|
|
5
|
+
|
|
6
|
+
# 读取 stdin(Claude Code 传入的 JSON)
|
|
7
|
+
INPUT=$(cat)
|
|
8
|
+
|
|
9
|
+
# 提取字段
|
|
10
|
+
TOOL_NAME="${CLAUDE_TOOL_NAME:-$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("tool_name",""))' 2>/dev/null || echo '')}"
|
|
11
|
+
TOOL_INPUT=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(json.dumps(d.get("tool_input",{})))' 2>/dev/null || echo '{}')
|
|
12
|
+
PROJECT_PATH=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("cwd",""))' 2>/dev/null || echo '')
|
|
13
|
+
PROJECT_PATH="${PROJECT_PATH:-${PWD}}"
|
|
14
|
+
|
|
15
|
+
# 构造事件 JSON(通过环境变量传参,避免 shell 注入)
|
|
16
|
+
EVENT=$(FORGE_TOOL_NAME="$TOOL_NAME" FORGE_TOOL_INPUT="$TOOL_INPUT" FORGE_PROJECT_PATH="$PROJECT_PATH" \
|
|
17
|
+
python3 -c "
|
|
18
|
+
import json, os
|
|
19
|
+
from datetime import datetime
|
|
20
|
+
tool_input_raw = os.environ.get('FORGE_TOOL_INPUT', '{}')
|
|
21
|
+
try:
|
|
22
|
+
tool_input = json.loads(tool_input_raw)
|
|
23
|
+
except Exception:
|
|
24
|
+
tool_input = {}
|
|
25
|
+
print(json.dumps({
|
|
26
|
+
'hook_type': 'PreToolUse',
|
|
27
|
+
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S'),
|
|
28
|
+
'session_id': os.environ.get('CLAUDE_CODE_SESSION_ID', 'cli'),
|
|
29
|
+
'project_path': os.environ.get('FORGE_PROJECT_PATH', ''),
|
|
30
|
+
'tool_name': os.environ.get('FORGE_TOOL_NAME', ''),
|
|
31
|
+
'tool_input': tool_input,
|
|
32
|
+
}))
|
|
33
|
+
" 2>/dev/null)
|
|
34
|
+
|
|
35
|
+
# 发送事件并等待响应(双向通信,5 秒超时)
|
|
36
|
+
RESPONSE=$(echo "$EVENT" | nc -U -w 5 "$SOCKET_PATH" 2>/dev/null)
|
|
37
|
+
|
|
38
|
+
if [ -n "$RESPONSE" ]; then
|
|
39
|
+
# 解析响应
|
|
40
|
+
ALLOW=$(echo "$RESPONSE" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(str(d.get("allow",True)).lower())' 2>/dev/null || echo 'true')
|
|
41
|
+
|
|
42
|
+
if [ "$ALLOW" = "false" ]; then
|
|
43
|
+
# 输出拦截 JSON 到 stdout(Claude Code 读取)
|
|
44
|
+
echo "$RESPONSE"
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# 有 additionalContext 时输出
|
|
49
|
+
HAS_CONTEXT=$(echo "$RESPONSE" | python3 -c 'import sys,json; d=json.load(sys.stdin); print("yes" if d.get("additionalContext") else "no")' 2>/dev/null || echo 'no')
|
|
50
|
+
if [ "$HAS_CONTEXT" = "yes" ]; then
|
|
51
|
+
echo "$RESPONSE"
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
exit 0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Claude Forge - Stop Hook
|
|
3
|
+
|
|
4
|
+
SOCKET_PATH="${CLAUDE_FORGE_SOCKET:-$HOME/.claude-forge/daemon.sock}"
|
|
5
|
+
|
|
6
|
+
# 读取 stdin
|
|
7
|
+
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
8
|
+
|
|
9
|
+
# 提取 cwd
|
|
10
|
+
PROJECT_PATH=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("cwd",""))' 2>/dev/null || echo '')
|
|
11
|
+
PROJECT_PATH="${PROJECT_PATH:-${PWD}}"
|
|
12
|
+
|
|
13
|
+
# 构造事件 JSON(通过环境变量传参,避免 shell 注入)
|
|
14
|
+
EVENT=$(FORGE_PROJECT_PATH="$PROJECT_PATH" \
|
|
15
|
+
python3 -c "
|
|
16
|
+
import json, os
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
print(json.dumps({
|
|
19
|
+
'hook_type': 'Stop',
|
|
20
|
+
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S'),
|
|
21
|
+
'session_id': os.environ.get('CLAUDE_CODE_SESSION_ID', 'cli'),
|
|
22
|
+
'project_path': os.environ.get('FORGE_PROJECT_PATH', ''),
|
|
23
|
+
'tool_name': 'stop',
|
|
24
|
+
'tool_input': {},
|
|
25
|
+
}))
|
|
26
|
+
" 2>/dev/null)
|
|
27
|
+
|
|
28
|
+
echo "$EVENT" | nc -U -w 1 "$SOCKET_PATH" 2>/dev/null || true
|
|
29
|
+
exit 0
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Claude Forge - UserPromptSubmit Hook
|
|
3
|
+
# 拦截用户输入,触发意图分析和自动 Pipeline 编排
|
|
4
|
+
|
|
5
|
+
SOCKET_PATH="${CLAUDE_FORGE_SOCKET:-$HOME/.claude-forge/daemon.sock}"
|
|
6
|
+
|
|
7
|
+
# daemon 未运行,快速跳过
|
|
8
|
+
if [ ! -S "$SOCKET_PATH" ]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
# 读取 stdin(Claude Code 传入的 JSON)
|
|
13
|
+
INPUT=$(cat)
|
|
14
|
+
|
|
15
|
+
# 提取字段
|
|
16
|
+
USER_PROMPT=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("prompt",""))' 2>/dev/null || echo '')
|
|
17
|
+
PROJECT_PATH=$(echo "$INPUT" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("cwd",""))' 2>/dev/null || echo '')
|
|
18
|
+
PROJECT_PATH="${PROJECT_PATH:-${PWD}}"
|
|
19
|
+
|
|
20
|
+
# 空 prompt 跳过
|
|
21
|
+
if [ -z "$USER_PROMPT" ]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# 安全地构造事件 JSON(通过环境变量传参,避免 shell 注入)
|
|
26
|
+
EVENT=$(FORGE_USER_PROMPT="$USER_PROMPT" FORGE_PROJECT_PATH="$PROJECT_PATH" \
|
|
27
|
+
python3 -c "
|
|
28
|
+
import json, os
|
|
29
|
+
from datetime import datetime
|
|
30
|
+
print(json.dumps({
|
|
31
|
+
'hook_type': 'UserPromptSubmit',
|
|
32
|
+
'timestamp': datetime.now().strftime('%Y-%m-%dT%H:%M:%S'),
|
|
33
|
+
'session_id': os.environ.get('CLAUDE_CODE_SESSION_ID', 'cli'),
|
|
34
|
+
'project_path': os.environ.get('FORGE_PROJECT_PATH', ''),
|
|
35
|
+
'tool_name': 'UserPrompt',
|
|
36
|
+
'tool_input': {'user_prompt': os.environ.get('FORGE_USER_PROMPT', '')},
|
|
37
|
+
}))
|
|
38
|
+
" 2>/dev/null)
|
|
39
|
+
|
|
40
|
+
if [ -z "$EVENT" ]; then
|
|
41
|
+
exit 0
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# 发送事件并等待响应(10 秒超时,AI 分析可能需要更多时间)
|
|
45
|
+
RESPONSE=$(echo "$EVENT" | nc -U -w 10 "$SOCKET_PATH" 2>/dev/null)
|
|
46
|
+
|
|
47
|
+
if [ -n "$RESPONSE" ]; then
|
|
48
|
+
HAS_CONTEXT=$(echo "$RESPONSE" | python3 -c 'import sys,json; d=json.load(sys.stdin); print("yes" if d.get("additionalContext") else "no")' 2>/dev/null || echo 'no')
|
|
49
|
+
if [ "$HAS_CONTEXT" = "yes" ]; then
|
|
50
|
+
# stderr 输出到终端,让用户实时看到决策过程
|
|
51
|
+
# 用 fd3 保存真实 stderr,python3 错误丢弃,面板输出保留
|
|
52
|
+
exec 3>&2
|
|
53
|
+
echo "$RESPONSE" | python3 -c '
|
|
54
|
+
import sys, json, os
|
|
55
|
+
d = json.load(sys.stdin)
|
|
56
|
+
ctx = d.get("additionalContext", "")
|
|
57
|
+
lines = []
|
|
58
|
+
for line in ctx.split("\n"):
|
|
59
|
+
if line.startswith("请在回复"):
|
|
60
|
+
break
|
|
61
|
+
if line.strip():
|
|
62
|
+
lines.append(line)
|
|
63
|
+
if lines:
|
|
64
|
+
os.write(3, ("\033[36m" + "\n".join(lines) + "\033[0m\n").encode())
|
|
65
|
+
' 2>/dev/null
|
|
66
|
+
exec 3>&-
|
|
67
|
+
# stdout 返回给 Claude Code
|
|
68
|
+
echo "$RESPONSE"
|
|
69
|
+
fi
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
exit 0
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ForgeEvent } from '../types/index.js';
|
|
2
|
+
import type { HookResponse } from '../daemon/server.js';
|
|
3
|
+
import type Database from 'better-sqlite3';
|
|
4
|
+
import { type PolicyRule } from './policy-engine.js';
|
|
5
|
+
export interface OrchestrationConfig {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
customRules?: PolicyRule[];
|
|
8
|
+
}
|
|
9
|
+
export declare class OrchestrationEngine {
|
|
10
|
+
private policy;
|
|
11
|
+
private notifier;
|
|
12
|
+
private tracker;
|
|
13
|
+
private enabled;
|
|
14
|
+
constructor(config: OrchestrationConfig);
|
|
15
|
+
/**
|
|
16
|
+
* PreToolUse 事件:策略评估 + 通知附带
|
|
17
|
+
*/
|
|
18
|
+
evaluatePreToolUse(event: ForgeEvent): HookResponse | null;
|
|
19
|
+
/**
|
|
20
|
+
* PostToolUse 事件:更新跟踪
|
|
21
|
+
*/
|
|
22
|
+
handlePostToolUse(event: ForgeEvent): void;
|
|
23
|
+
/**
|
|
24
|
+
* 外部推送通知(蒸馏完成、CLAUDE.md 生成等)
|
|
25
|
+
*/
|
|
26
|
+
pushNotification(message: string): void;
|
|
27
|
+
flushNotifications(): string | null;
|
|
28
|
+
setTrackerDatabase(db: Database.Database): void;
|
|
29
|
+
getStatus(): import("./tracker.js").SessionStatus;
|
|
30
|
+
getTrackerStats(days?: number): import("./tracker.js").TrackerStats | null;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/orchestration/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKnE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,mBAAmB;IAOvC;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI;IAiC1D;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK1C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIvC,kBAAkB,IAAI,MAAM,GAAG,IAAI;IAInC,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAI/C,SAAS;IAIT,eAAe,CAAC,IAAI,SAAI;CAGzB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { PolicyEngine } from './policy-engine.js';
|
|
2
|
+
import { Notifier } from './notifier.js';
|
|
3
|
+
import { ExecutionTracker } from './tracker.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
export class OrchestrationEngine {
|
|
6
|
+
policy;
|
|
7
|
+
notifier;
|
|
8
|
+
tracker;
|
|
9
|
+
enabled;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.enabled = config.enabled;
|
|
12
|
+
this.policy = new PolicyEngine(config.customRules);
|
|
13
|
+
this.notifier = new Notifier();
|
|
14
|
+
this.tracker = new ExecutionTracker();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* PreToolUse 事件:策略评估 + 通知附带
|
|
18
|
+
*/
|
|
19
|
+
evaluatePreToolUse(event) {
|
|
20
|
+
if (!this.enabled)
|
|
21
|
+
return null;
|
|
22
|
+
// 1. 策略评估
|
|
23
|
+
const decision = this.policy.evaluate(event);
|
|
24
|
+
if (decision && !decision.allow) {
|
|
25
|
+
logger.info(`策略已拦截:${decision.reason}`);
|
|
26
|
+
return { allow: false, reason: decision.reason };
|
|
27
|
+
}
|
|
28
|
+
// 2. 更新跟踪器
|
|
29
|
+
this.tracker.track(event);
|
|
30
|
+
// 3. 收集需要注入的上下文
|
|
31
|
+
const contextParts = [];
|
|
32
|
+
if (decision?.context) {
|
|
33
|
+
contextParts.push(decision.context);
|
|
34
|
+
}
|
|
35
|
+
// 待发送通知
|
|
36
|
+
const notifications = this.notifier.flush();
|
|
37
|
+
if (notifications) {
|
|
38
|
+
contextParts.push(notifications);
|
|
39
|
+
}
|
|
40
|
+
if (contextParts.length > 0) {
|
|
41
|
+
return { allow: true, additionalContext: contextParts.join('\n') };
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* PostToolUse 事件:更新跟踪
|
|
47
|
+
*/
|
|
48
|
+
handlePostToolUse(event) {
|
|
49
|
+
if (!this.enabled)
|
|
50
|
+
return;
|
|
51
|
+
this.tracker.track(event);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 外部推送通知(蒸馏完成、CLAUDE.md 生成等)
|
|
55
|
+
*/
|
|
56
|
+
pushNotification(message) {
|
|
57
|
+
this.notifier.push(message);
|
|
58
|
+
}
|
|
59
|
+
flushNotifications() {
|
|
60
|
+
return this.notifier.flush();
|
|
61
|
+
}
|
|
62
|
+
setTrackerDatabase(db) {
|
|
63
|
+
this.tracker.setDatabase(db);
|
|
64
|
+
}
|
|
65
|
+
getStatus() {
|
|
66
|
+
return this.tracker.getStatus();
|
|
67
|
+
}
|
|
68
|
+
getTrackerStats(days = 7) {
|
|
69
|
+
return this.tracker.getStats(days);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/orchestration/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAO5C,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAe;IACrB,QAAQ,CAAW;IACnB,OAAO,CAAmB;IAC1B,OAAO,CAAU;IAEzB,YAAY,MAA2B;QACrC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,KAAiB;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE/B,UAAU;QACV,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;QACnD,CAAC;QAED,WAAW;QACX,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE1B,gBAAgB;QAChB,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,QAAQ;QACR,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC5C,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,KAAiB;QACjC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,OAAe;QAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,kBAAkB,CAAC,EAAqB;QACtC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;IAClC,CAAC;IAED,eAAe,CAAC,IAAI,GAAG,CAAC;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class Notifier {
|
|
2
|
+
private pendingNotifications;
|
|
3
|
+
push(message: string): void;
|
|
4
|
+
/**
|
|
5
|
+
* 获取所有待发送通知并清空队列
|
|
6
|
+
* 格式化为单条 additionalContext 字符串
|
|
7
|
+
*/
|
|
8
|
+
flush(): string | null;
|
|
9
|
+
get pendingCount(): number;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=notifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/orchestration/notifier.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAQ;IACnB,OAAO,CAAC,oBAAoB,CAAgB;IAE5C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3B;;;OAGG;IACH,KAAK,IAAI,MAAM,GAAG,IAAI;IAOtB,IAAI,YAAY,IAAI,MAAM,CAEzB;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
export class Notifier {
|
|
3
|
+
pendingNotifications = [];
|
|
4
|
+
push(message) {
|
|
5
|
+
this.pendingNotifications.push(message);
|
|
6
|
+
logger.info(`通知已入队:${message}`);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 获取所有待发送通知并清空队列
|
|
10
|
+
* 格式化为单条 additionalContext 字符串
|
|
11
|
+
*/
|
|
12
|
+
flush() {
|
|
13
|
+
if (this.pendingNotifications.length === 0)
|
|
14
|
+
return null;
|
|
15
|
+
const messages = this.pendingNotifications.splice(0);
|
|
16
|
+
return messages.join('\n');
|
|
17
|
+
}
|
|
18
|
+
get pendingCount() {
|
|
19
|
+
return this.pendingNotifications.length;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=notifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifier.js","sourceRoot":"","sources":["../../src/orchestration/notifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,OAAO,QAAQ;IACX,oBAAoB,GAAa,EAAE,CAAC;IAE5C,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,oBAAoB,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAExD,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ForgeEvent } from '../types/index.js';
|
|
2
|
+
export interface PolicyRule {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
tool: string;
|
|
6
|
+
pattern: string;
|
|
7
|
+
action: 'deny' | 'warn' | 'allow';
|
|
8
|
+
reason: string;
|
|
9
|
+
context?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PolicyDecision {
|
|
12
|
+
allow: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
context?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class PolicyEngine {
|
|
17
|
+
private rules;
|
|
18
|
+
constructor(customRules?: PolicyRule[]);
|
|
19
|
+
evaluate(event: ForgeEvent): PolicyDecision | null;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=policy-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../../src/orchestration/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAgDD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAe;gBAEhB,WAAW,GAAE,UAAU,EAAO;IAI1C,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc,GAAG,IAAI;CA8BnD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
/** 内置安全规则 */
|
|
3
|
+
const BUILTIN_RULES = [
|
|
4
|
+
{
|
|
5
|
+
id: 'no-rm-rf-root',
|
|
6
|
+
name: '禁止删除根目录',
|
|
7
|
+
tool: 'Bash',
|
|
8
|
+
pattern: 'rm\\s+-[^\\s]*r[^\\s]*f[^\\s]*\\s+/',
|
|
9
|
+
action: 'deny',
|
|
10
|
+
reason: '危险操作:禁止对根目录执行 rm -rf',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: 'no-sudo-rm',
|
|
14
|
+
name: '禁止 sudo 删除',
|
|
15
|
+
tool: 'Bash',
|
|
16
|
+
pattern: 'sudo\\s+rm\\s+-[^\\s]*r',
|
|
17
|
+
action: 'deny',
|
|
18
|
+
reason: '危险操作:禁止 sudo rm -r',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: 'warn-force-push',
|
|
22
|
+
name: 'force push 警告',
|
|
23
|
+
tool: 'Bash',
|
|
24
|
+
pattern: 'git\\s+push\\s+.*--force',
|
|
25
|
+
action: 'warn',
|
|
26
|
+
reason: '警告:force push 可能覆盖远程历史',
|
|
27
|
+
context: '[Forge 警告] 检测到 git push --force,请确认这是有意为之。force push 会覆盖远程仓库的提交历史。',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'no-chmod-777',
|
|
31
|
+
name: '禁止 chmod 777',
|
|
32
|
+
tool: 'Bash',
|
|
33
|
+
pattern: 'chmod\\s+777',
|
|
34
|
+
action: 'deny',
|
|
35
|
+
reason: '安全风险:禁止设置 777 权限',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'warn-drop-table',
|
|
39
|
+
name: 'DROP TABLE 警告',
|
|
40
|
+
tool: 'Bash',
|
|
41
|
+
pattern: 'DROP\\s+TABLE|DROP\\s+DATABASE',
|
|
42
|
+
action: 'warn',
|
|
43
|
+
reason: '警告:检测到数据库删除操作',
|
|
44
|
+
context: '[Forge 警告] 检测到 DROP TABLE/DATABASE 操作,请确认不会误删生产数据。',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
export class PolicyEngine {
|
|
48
|
+
rules;
|
|
49
|
+
constructor(customRules = []) {
|
|
50
|
+
this.rules = [...BUILTIN_RULES, ...customRules];
|
|
51
|
+
}
|
|
52
|
+
evaluate(event) {
|
|
53
|
+
if (event.hook_type !== 'PreToolUse')
|
|
54
|
+
return null;
|
|
55
|
+
const toolName = event.tool_name || '';
|
|
56
|
+
const inputStr = event.tool_input ? JSON.stringify(event.tool_input) : '';
|
|
57
|
+
for (const rule of this.rules) {
|
|
58
|
+
// 匹配工具名
|
|
59
|
+
if (rule.tool && !new RegExp(rule.tool, 'i').test(toolName)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// 匹配 input 内容
|
|
63
|
+
if (rule.pattern && !new RegExp(rule.pattern, 'i').test(inputStr)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
logger.info(`策略匹配:${rule.name} (${rule.action})`);
|
|
67
|
+
if (rule.action === 'deny') {
|
|
68
|
+
return { allow: false, reason: rule.reason };
|
|
69
|
+
}
|
|
70
|
+
if (rule.action === 'warn') {
|
|
71
|
+
return { allow: true, context: rule.context || rule.reason };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null; // 无匹配规则,放行
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=policy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../src/orchestration/policy-engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAkB5C,aAAa;AACb,MAAM,aAAa,GAAiB;IAClC;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,qCAAqC;QAC9C,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,sBAAsB;KAC/B;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,yBAAyB;QAClC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,oBAAoB;KAC7B;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,0BAA0B;QACnC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,wBAAwB;QAChC,OAAO,EAAE,oEAAoE;KAC9E;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,kBAAkB;KAC3B;IACD;QACE,EAAE,EAAE,iBAAiB;QACrB,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,gCAAgC;QACzC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,eAAe;QACvB,OAAO,EAAE,oDAAoD;KAC9D;CACF,CAAC;AAEF,MAAM,OAAO,YAAY;IACf,KAAK,CAAe;IAE5B,YAAY,cAA4B,EAAE;QACxC,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC;IAClD,CAAC;IAED,QAAQ,CAAC,KAAiB;QACxB,IAAI,KAAK,CAAC,SAAS,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QAElD,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE1E,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,QAAQ;YACR,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5D,SAAS;YACX,CAAC;YAED,cAAc;YACd,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClE,SAAS;YACX,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/C,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/D,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,CAAC,WAAW;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ForgeEvent } from '../types/index.js';
|
|
2
|
+
import type Database from 'better-sqlite3';
|
|
3
|
+
export interface SessionStatus {
|
|
4
|
+
toolCallCount: number;
|
|
5
|
+
fileEditCount: number;
|
|
6
|
+
filesEdited: string[];
|
|
7
|
+
lastTool: string | null;
|
|
8
|
+
lastTime: string | null;
|
|
9
|
+
duration: string;
|
|
10
|
+
}
|
|
11
|
+
export interface TrackerStats {
|
|
12
|
+
totalSessions: number;
|
|
13
|
+
totalToolCalls: number;
|
|
14
|
+
totalFilesEdited: number;
|
|
15
|
+
topTools: Array<{
|
|
16
|
+
tool: string;
|
|
17
|
+
count: number;
|
|
18
|
+
}>;
|
|
19
|
+
topFiles: Array<{
|
|
20
|
+
file: string;
|
|
21
|
+
count: number;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 执行跟踪器 — 内存跟踪当前会话,同时持久化到 SQLite 供跨会话统计
|
|
26
|
+
*/
|
|
27
|
+
export declare class ExecutionTracker {
|
|
28
|
+
private toolCalls;
|
|
29
|
+
private editedFiles;
|
|
30
|
+
private startTime;
|
|
31
|
+
private db;
|
|
32
|
+
/**
|
|
33
|
+
* 注入 SQLite 实例以启用持久化(可选)
|
|
34
|
+
*/
|
|
35
|
+
setDatabase(db: Database.Database): void;
|
|
36
|
+
private ensureSchema;
|
|
37
|
+
track(event: ForgeEvent): void;
|
|
38
|
+
getStatus(): SessionStatus;
|
|
39
|
+
/**
|
|
40
|
+
* 跨会话统计(需要 SQLite)
|
|
41
|
+
*/
|
|
42
|
+
getStats(days?: number): TrackerStats | null;
|
|
43
|
+
reset(): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/orchestration/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,EAAE,CAAkC;IAE5C;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAKxC,OAAO,CAAC,YAAY;IAiBpB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAuB9B,SAAS,IAAI,aAAa;IAe1B;;OAEG;IACH,QAAQ,CAAC,IAAI,SAAI,GAAG,YAAY,GAAG,IAAI;IAgCvC,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 执行跟踪器 — 内存跟踪当前会话,同时持久化到 SQLite 供跨会话统计
|
|
3
|
+
*/
|
|
4
|
+
export class ExecutionTracker {
|
|
5
|
+
toolCalls = [];
|
|
6
|
+
editedFiles = new Set();
|
|
7
|
+
startTime = new Date().toISOString();
|
|
8
|
+
db = null;
|
|
9
|
+
/**
|
|
10
|
+
* 注入 SQLite 实例以启用持久化(可选)
|
|
11
|
+
*/
|
|
12
|
+
setDatabase(db) {
|
|
13
|
+
this.db = db;
|
|
14
|
+
this.ensureSchema();
|
|
15
|
+
}
|
|
16
|
+
ensureSchema() {
|
|
17
|
+
if (!this.db)
|
|
18
|
+
return;
|
|
19
|
+
this.db.exec(`
|
|
20
|
+
CREATE TABLE IF NOT EXISTS tracker_tool_calls (
|
|
21
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
22
|
+
session_id TEXT NOT NULL,
|
|
23
|
+
tool_name TEXT NOT NULL,
|
|
24
|
+
file_path TEXT,
|
|
25
|
+
timestamp TEXT NOT NULL,
|
|
26
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
27
|
+
);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_tracker_session ON tracker_tool_calls(session_id);
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_tracker_tool ON tracker_tool_calls(tool_name);
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_tracker_ts ON tracker_tool_calls(timestamp DESC);
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
track(event) {
|
|
34
|
+
if (!event.tool_name)
|
|
35
|
+
return;
|
|
36
|
+
this.toolCalls.push({ tool: event.tool_name, time: event.timestamp });
|
|
37
|
+
const filePath = event.tool_input?.file_path;
|
|
38
|
+
if (['Edit', 'Write', 'MultiEdit'].includes(event.tool_name) && filePath) {
|
|
39
|
+
this.editedFiles.add(filePath);
|
|
40
|
+
}
|
|
41
|
+
// 持久化到 SQLite
|
|
42
|
+
if (this.db) {
|
|
43
|
+
try {
|
|
44
|
+
this.db.prepare(`
|
|
45
|
+
INSERT INTO tracker_tool_calls (session_id, tool_name, file_path, timestamp)
|
|
46
|
+
VALUES (?, ?, ?, ?)
|
|
47
|
+
`).run(event.session_id, event.tool_name, filePath ?? null, event.timestamp);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// 持久化失败不影响内存跟踪
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
getStatus() {
|
|
55
|
+
const last = this.toolCalls[this.toolCalls.length - 1];
|
|
56
|
+
const start = new Date(this.startTime).getTime();
|
|
57
|
+
const mins = Math.floor((Date.now() - start) / 60000);
|
|
58
|
+
return {
|
|
59
|
+
toolCallCount: this.toolCalls.length,
|
|
60
|
+
fileEditCount: this.editedFiles.size,
|
|
61
|
+
filesEdited: [...this.editedFiles],
|
|
62
|
+
lastTool: last?.tool ?? null,
|
|
63
|
+
lastTime: last?.time ?? null,
|
|
64
|
+
duration: mins < 60 ? `${mins}分钟` : `${Math.floor(mins / 60)}小时${mins % 60}分钟`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 跨会话统计(需要 SQLite)
|
|
69
|
+
*/
|
|
70
|
+
getStats(days = 7) {
|
|
71
|
+
if (!this.db)
|
|
72
|
+
return null;
|
|
73
|
+
const cutoff = new Date(Date.now() - days * 86400000).toISOString();
|
|
74
|
+
const totalSessions = this.db.prepare('SELECT COUNT(DISTINCT session_id) as c FROM tracker_tool_calls WHERE timestamp > ?').get(cutoff).c;
|
|
75
|
+
const totalToolCalls = this.db.prepare('SELECT COUNT(*) as c FROM tracker_tool_calls WHERE timestamp > ?').get(cutoff).c;
|
|
76
|
+
const totalFilesEdited = this.db.prepare('SELECT COUNT(DISTINCT file_path) as c FROM tracker_tool_calls WHERE file_path IS NOT NULL AND timestamp > ?').get(cutoff).c;
|
|
77
|
+
const topTools = this.db.prepare(`
|
|
78
|
+
SELECT tool_name as tool, COUNT(*) as count
|
|
79
|
+
FROM tracker_tool_calls WHERE timestamp > ?
|
|
80
|
+
GROUP BY tool_name ORDER BY count DESC LIMIT 10
|
|
81
|
+
`).all(cutoff);
|
|
82
|
+
const topFiles = this.db.prepare(`
|
|
83
|
+
SELECT file_path as file, COUNT(*) as count
|
|
84
|
+
FROM tracker_tool_calls WHERE file_path IS NOT NULL AND timestamp > ?
|
|
85
|
+
GROUP BY file_path ORDER BY count DESC LIMIT 10
|
|
86
|
+
`).all(cutoff);
|
|
87
|
+
return { totalSessions, totalToolCalls, totalFilesEdited, topTools, topFiles };
|
|
88
|
+
}
|
|
89
|
+
reset() {
|
|
90
|
+
this.toolCalls = [];
|
|
91
|
+
this.editedFiles.clear();
|
|
92
|
+
this.startTime = new Date().toISOString();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/orchestration/tracker.ts"],"names":[],"mappings":"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"}
|