@claude-flow/cli 3.32.3 → 3.32.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/helpers/helpers.manifest.json +2 -2
- package/catalog-manifest.json +2 -2
- package/dist/src/agenticow/speculative-exploration.d.ts +148 -0
- package/dist/src/agenticow/speculative-exploration.js +218 -0
- package/dist/src/appliance/gguf-engine.d.ts +91 -0
- package/dist/src/appliance/gguf-engine.js +425 -0
- package/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
- package/dist/src/appliance/ruvllm-bridge.js +292 -0
- package/dist/src/appliance/rvfa-builder.d.ts +44 -0
- package/dist/src/appliance/rvfa-builder.js +329 -0
- package/dist/src/appliance/rvfa-distribution.d.ts +97 -0
- package/dist/src/appliance/rvfa-distribution.js +370 -0
- package/dist/src/appliance/rvfa-format.d.ts +111 -0
- package/dist/src/appliance/rvfa-format.js +393 -0
- package/dist/src/appliance/rvfa-runner.d.ts +69 -0
- package/dist/src/appliance/rvfa-runner.js +237 -0
- package/dist/src/appliance/rvfa-signing.d.ts +123 -0
- package/dist/src/appliance/rvfa-signing.js +347 -0
- package/dist/src/auth/client.d.ts +89 -0
- package/dist/src/auth/client.js +242 -0
- package/dist/src/auth/constants.d.ts +7 -0
- package/dist/src/auth/constants.js +7 -0
- package/dist/src/auth/scopes.d.ts +14 -0
- package/dist/src/auth/scopes.js +21 -0
- package/dist/src/auth/security-bridge.d.ts +36 -0
- package/dist/src/auth/security-bridge.js +42 -0
- package/dist/src/auth/session.d.ts +20 -0
- package/dist/src/auth/session.js +32 -0
- package/dist/src/auth/state.d.ts +19 -0
- package/dist/src/auth/state.js +53 -0
- package/dist/src/auth/types.d.ts +27 -0
- package/dist/src/auth/types.js +11 -0
- package/dist/src/autopilot-state.d.ts +77 -0
- package/dist/src/autopilot-state.js +271 -0
- package/dist/src/benchmarks/gaia-agent-planning.smoke.d.ts +18 -0
- package/dist/src/benchmarks/gaia-agent-planning.smoke.js +253 -0
- package/dist/src/benchmarks/gaia-agent.d.ts +198 -0
- package/dist/src/benchmarks/gaia-agent.js +651 -0
- package/dist/src/benchmarks/gaia-causal-memory.d.ts +133 -0
- package/dist/src/benchmarks/gaia-causal-memory.js +281 -0
- package/dist/src/benchmarks/gaia-causal-memory.smoke.d.ts +22 -0
- package/dist/src/benchmarks/gaia-causal-memory.smoke.js +300 -0
- package/dist/src/benchmarks/gaia-convergence.d.ts +138 -0
- package/dist/src/benchmarks/gaia-convergence.js +260 -0
- package/dist/src/benchmarks/gaia-convergence.smoke.d.ts +19 -0
- package/dist/src/benchmarks/gaia-convergence.smoke.js +246 -0
- package/dist/src/benchmarks/gaia-critic.d.ts +123 -0
- package/dist/src/benchmarks/gaia-critic.js +312 -0
- package/dist/src/benchmarks/gaia-critic.smoke.d.ts +21 -0
- package/dist/src/benchmarks/gaia-critic.smoke.js +327 -0
- package/dist/src/benchmarks/gaia-decomposer.d.ts +125 -0
- package/dist/src/benchmarks/gaia-decomposer.js +350 -0
- package/dist/src/benchmarks/gaia-decomposer.smoke.d.ts +21 -0
- package/dist/src/benchmarks/gaia-decomposer.smoke.js +228 -0
- package/dist/src/benchmarks/gaia-e2e-smoke.d.ts +27 -0
- package/dist/src/benchmarks/gaia-e2e-smoke.js +136 -0
- package/dist/src/benchmarks/gaia-extract.smoke.d.ts +45 -0
- package/dist/src/benchmarks/gaia-extract.smoke.js +242 -0
- package/dist/src/benchmarks/gaia-hardness/features.d.ts +46 -0
- package/dist/src/benchmarks/gaia-hardness/features.js +170 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.d.ts +105 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.js +260 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.smoke.d.ts +20 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.smoke.js +235 -0
- package/dist/src/benchmarks/gaia-hardness/train-data-loader.d.ts +51 -0
- package/dist/src/benchmarks/gaia-hardness/train-data-loader.js +179 -0
- package/dist/src/benchmarks/gaia-judge.d.ts +88 -0
- package/dist/src/benchmarks/gaia-judge.js +437 -0
- package/dist/src/benchmarks/gaia-loader.d.ts +87 -0
- package/dist/src/benchmarks/gaia-loader.js +326 -0
- package/dist/src/benchmarks/gaia-tools/file_read.d.ts +35 -0
- package/dist/src/benchmarks/gaia-tools/file_read.js +403 -0
- package/dist/src/benchmarks/gaia-tools/grounded_query.d.ts +126 -0
- package/dist/src/benchmarks/gaia-tools/grounded_query.js +225 -0
- package/dist/src/benchmarks/gaia-tools/index.d.ts +32 -0
- package/dist/src/benchmarks/gaia-tools/index.js +36 -0
- package/dist/src/benchmarks/gaia-tools/types.d.ts +62 -0
- package/dist/src/benchmarks/gaia-tools/types.js +12 -0
- package/dist/src/benchmarks/gaia-tools/web_search.d.ts +30 -0
- package/dist/src/benchmarks/gaia-tools/web_search.js +210 -0
- package/dist/src/benchmarks/gaia-voting.d.ts +88 -0
- package/dist/src/benchmarks/gaia-voting.js +297 -0
- package/dist/src/benchmarks/gaia-voting.smoke.d.ts +20 -0
- package/dist/src/benchmarks/gaia-voting.smoke.js +332 -0
- package/dist/src/benchmarks/pretrain/index.d.ts +58 -0
- package/dist/src/benchmarks/pretrain/index.js +404 -0
- package/dist/src/business-pods/bbs-budget-tracker.d.ts +139 -0
- package/dist/src/business-pods/bbs-budget-tracker.js +358 -0
- package/dist/src/business-pods/domain-affinity-policy.d.ts +47 -0
- package/dist/src/business-pods/domain-affinity-policy.js +65 -0
- package/dist/src/business-pods/pod-schema.d.ts +96 -0
- package/dist/src/business-pods/pod-schema.js +225 -0
- package/dist/src/commands/advisor.d.ts +15 -0
- package/dist/src/commands/advisor.js +94 -0
- package/dist/src/commands/agent-wasm.d.ts +14 -0
- package/dist/src/commands/agent-wasm.js +333 -0
- package/dist/src/commands/agent.d.ts +8 -0
- package/dist/src/commands/agent.js +927 -0
- package/dist/src/commands/analyze.d.ts +19 -0
- package/dist/src/commands/analyze.js +2047 -0
- package/dist/src/commands/announcements.d.ts +17 -0
- package/dist/src/commands/announcements.js +0 -0
- package/dist/src/commands/appliance-advanced.d.ts +9 -0
- package/dist/src/commands/appliance-advanced.js +215 -0
- package/dist/src/commands/appliance.d.ts +8 -0
- package/dist/src/commands/appliance.js +404 -0
- package/dist/src/commands/auth.d.ts +15 -0
- package/dist/src/commands/auth.js +244 -0
- package/dist/src/commands/autopilot.d.ts +15 -0
- package/dist/src/commands/autopilot.js +407 -0
- package/dist/src/commands/benchmark.d.ts +10 -0
- package/dist/src/commands/benchmark.js +460 -0
- package/dist/src/commands/claims.d.ts +10 -0
- package/dist/src/commands/claims.js +620 -0
- package/dist/src/commands/cleanup.d.ts +13 -0
- package/dist/src/commands/cleanup.js +250 -0
- package/dist/src/commands/completions.d.ts +10 -0
- package/dist/src/commands/completions.js +539 -0
- package/dist/src/commands/config.d.ts +8 -0
- package/dist/src/commands/config.js +428 -0
- package/dist/src/commands/daemon.d.ts +59 -0
- package/dist/src/commands/daemon.js +1733 -0
- package/dist/src/commands/deployment.d.ts +10 -0
- package/dist/src/commands/deployment.js +672 -0
- package/dist/src/commands/doctor.d.ts +10 -0
- package/dist/src/commands/doctor.js +1902 -0
- package/dist/src/commands/eject.d.ts +33 -0
- package/dist/src/commands/eject.js +195 -0
- package/dist/src/commands/embeddings.d.ts +18 -0
- package/dist/src/commands/embeddings.js +1623 -0
- package/dist/src/commands/funnel.d.ts +18 -0
- package/dist/src/commands/funnel.js +302 -0
- package/dist/src/commands/gaia-bench.d.ts +40 -0
- package/dist/src/commands/gaia-bench.js +597 -0
- package/dist/src/commands/guidance.d.ts +8 -0
- package/dist/src/commands/guidance.js +556 -0
- package/dist/src/commands/hive-mind.d.ts +11 -0
- package/dist/src/commands/hive-mind.js +1319 -0
- package/dist/src/commands/hooks.d.ts +8 -0
- package/dist/src/commands/hooks.js +4606 -0
- package/dist/src/commands/index.d.ts +118 -0
- package/dist/src/commands/index.js +366 -0
- package/dist/src/commands/init.d.ts +13 -0
- package/dist/src/commands/init.js +1297 -0
- package/dist/src/commands/issues.d.ts +21 -0
- package/dist/src/commands/issues.js +567 -0
- package/dist/src/commands/mcp.d.ts +11 -0
- package/dist/src/commands/mcp.js +732 -0
- package/dist/src/commands/memory-backup.d.ts +11 -0
- package/dist/src/commands/memory-backup.js +46 -0
- package/dist/src/commands/memory-distill.d.ts +27 -0
- package/dist/src/commands/memory-distill.js +374 -0
- package/dist/src/commands/memory.d.ts +8 -0
- package/dist/src/commands/memory.js +1596 -0
- package/dist/src/commands/metaharness.d.ts +39 -0
- package/dist/src/commands/metaharness.js +215 -0
- package/dist/src/commands/migrate.d.ts +8 -0
- package/dist/src/commands/migrate.js +742 -0
- package/dist/src/commands/neural.d.ts +10 -0
- package/dist/src/commands/neural.js +4331 -0
- package/dist/src/commands/performance.d.ts +10 -0
- package/dist/src/commands/performance.js +583 -0
- package/dist/src/commands/plugins.d.ts +11 -0
- package/dist/src/commands/plugins.js +826 -0
- package/dist/src/commands/process.d.ts +10 -0
- package/dist/src/commands/process.js +694 -0
- package/dist/src/commands/progress.d.ts +11 -0
- package/dist/src/commands/progress.js +259 -0
- package/dist/src/commands/providers.d.ts +10 -0
- package/dist/src/commands/providers.js +502 -0
- package/dist/src/commands/proxy-lifecycle.d.ts +12 -0
- package/dist/src/commands/proxy-lifecycle.js +232 -0
- package/dist/src/commands/proxy.d.ts +21 -0
- package/dist/src/commands/proxy.js +398 -0
- package/dist/src/commands/route.d.ts +16 -0
- package/dist/src/commands/route.js +822 -0
- package/dist/src/commands/ruvector/backup.d.ts +11 -0
- package/dist/src/commands/ruvector/backup.js +747 -0
- package/dist/src/commands/ruvector/benchmark.d.ts +11 -0
- package/dist/src/commands/ruvector/benchmark.js +490 -0
- package/dist/src/commands/ruvector/import.d.ts +18 -0
- package/dist/src/commands/ruvector/import.js +373 -0
- package/dist/src/commands/ruvector/index.d.ts +29 -0
- package/dist/src/commands/ruvector/index.js +129 -0
- package/dist/src/commands/ruvector/init.d.ts +11 -0
- package/dist/src/commands/ruvector/init.js +467 -0
- package/dist/src/commands/ruvector/migrate.d.ts +11 -0
- package/dist/src/commands/ruvector/migrate.js +498 -0
- package/dist/src/commands/ruvector/optimize.d.ts +11 -0
- package/dist/src/commands/ruvector/optimize.js +505 -0
- package/dist/src/commands/ruvector/pg-utils.d.ts +14 -0
- package/dist/src/commands/ruvector/pg-utils.js +41 -0
- package/dist/src/commands/ruvector/setup.d.ts +18 -0
- package/dist/src/commands/ruvector/setup.js +765 -0
- package/dist/src/commands/ruvector/status.d.ts +11 -0
- package/dist/src/commands/ruvector/status.js +479 -0
- package/dist/src/commands/security.d.ts +10 -0
- package/dist/src/commands/security.js +1012 -0
- package/dist/src/commands/session.d.ts +8 -0
- package/dist/src/commands/session.js +757 -0
- package/dist/src/commands/settings.d.ts +19 -0
- package/dist/src/commands/settings.js +180 -0
- package/dist/src/commands/spinner.d.ts +16 -0
- package/dist/src/commands/spinner.js +329 -0
- package/dist/src/commands/start.d.ts +8 -0
- package/dist/src/commands/start.js +418 -0
- package/dist/src/commands/status.d.ts +8 -0
- package/dist/src/commands/status.js +608 -0
- package/dist/src/commands/swarm.d.ts +8 -0
- package/dist/src/commands/swarm.js +891 -0
- package/dist/src/commands/task.d.ts +8 -0
- package/dist/src/commands/task.js +675 -0
- package/dist/src/commands/transfer-store.d.ts +13 -0
- package/dist/src/commands/transfer-store.js +428 -0
- package/dist/src/commands/update.d.ts +8 -0
- package/dist/src/commands/update.js +276 -0
- package/dist/src/commands/verify.d.ts +19 -0
- package/dist/src/commands/verify.js +261 -0
- package/dist/src/commands/version.d.ts +42 -0
- package/dist/src/commands/version.js +106 -0
- package/dist/src/commands/workflow.d.ts +8 -0
- package/dist/src/commands/workflow.js +617 -0
- package/dist/src/config/harness-feedback-applier.d.ts +50 -0
- package/dist/src/config/harness-feedback-applier.js +122 -0
- package/dist/src/config/proven-config-refresh.d.ts +39 -0
- package/dist/src/config/proven-config-refresh.js +154 -0
- package/dist/src/config/proven-config-rvfa.d.ts +23 -0
- package/dist/src/config/proven-config-rvfa.js +73 -0
- package/dist/src/config/proven-config.d.ts +86 -0
- package/dist/src/config/proven-config.js +176 -0
- package/dist/src/config-adapter.d.ts +15 -0
- package/dist/src/config-adapter.js +186 -0
- package/dist/src/encryption/vault.d.ts +94 -0
- package/dist/src/encryption/vault.js +172 -0
- package/dist/src/fs-secure.d.ts +86 -0
- package/dist/src/fs-secure.js +133 -0
- package/dist/src/funnel/advisor-tip.d.ts +58 -0
- package/dist/src/funnel/advisor-tip.js +92 -0
- package/dist/src/funnel/attribution.d.ts +37 -0
- package/dist/src/funnel/attribution.js +101 -0
- package/dist/src/funnel/consent.d.ts +22 -0
- package/dist/src/funnel/consent.js +58 -0
- package/dist/src/funnel/credit-errors.d.ts +31 -0
- package/dist/src/funnel/credit-errors.js +88 -0
- package/dist/src/funnel/credit-notifier.d.ts +44 -0
- package/dist/src/funnel/credit-notifier.js +74 -0
- package/dist/src/funnel/disclosure.d.ts +47 -0
- package/dist/src/funnel/disclosure.js +109 -0
- package/dist/src/funnel/enrollment.d.ts +36 -0
- package/dist/src/funnel/enrollment.js +64 -0
- package/dist/src/funnel/environment.d.ts +17 -0
- package/dist/src/funnel/environment.js +39 -0
- package/dist/src/funnel/event-transport.d.ts +51 -0
- package/dist/src/funnel/event-transport.js +199 -0
- package/dist/src/funnel/events.d.ts +42 -0
- package/dist/src/funnel/events.js +150 -0
- package/dist/src/funnel/index.d.ts +21 -0
- package/dist/src/funnel/index.js +21 -0
- package/dist/src/funnel/insights.d.ts +50 -0
- package/dist/src/funnel/insights.js +120 -0
- package/dist/src/funnel/local-signals.d.ts +20 -0
- package/dist/src/funnel/local-signals.js +77 -0
- package/dist/src/funnel/message-transport.d.ts +51 -0
- package/dist/src/funnel/message-transport.js +149 -0
- package/dist/src/funnel/messages.d.ts +55 -0
- package/dist/src/funnel/messages.js +160 -0
- package/dist/src/funnel/payout.d.ts +40 -0
- package/dist/src/funnel/payout.js +60 -0
- package/dist/src/funnel/power-saver-notifier.d.ts +44 -0
- package/dist/src/funnel/power-saver-notifier.js +92 -0
- package/dist/src/funnel/precedence.d.ts +16 -0
- package/dist/src/funnel/precedence.js +85 -0
- package/dist/src/funnel/promo.d.ts +41 -0
- package/dist/src/funnel/promo.js +144 -0
- package/dist/src/funnel/rate-limit-notifier.d.ts +55 -0
- package/dist/src/funnel/rate-limit-notifier.js +102 -0
- package/dist/src/funnel/rotation.d.ts +19 -0
- package/dist/src/funnel/rotation.js +70 -0
- package/dist/src/funnel/state.d.ts +13 -0
- package/dist/src/funnel/state.js +52 -0
- package/dist/src/funnel/toggle-cooldown.d.ts +17 -0
- package/dist/src/funnel/toggle-cooldown.js +32 -0
- package/dist/src/funnel/types.d.ts +98 -0
- package/dist/src/funnel/types.js +26 -0
- package/dist/src/index.d.ts +81 -0
- package/dist/src/index.js +609 -0
- package/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
- package/dist/src/infrastructure/in-memory-repositories.js +264 -0
- package/dist/src/init/claudemd-generator.d.ts +16 -0
- package/dist/src/init/claudemd-generator.js +368 -0
- package/dist/src/init/executor.d.ts +41 -0
- package/dist/src/init/executor.js +2142 -0
- package/dist/src/init/helper-refresh.d.ts +79 -0
- package/dist/src/init/helper-refresh.js +347 -0
- package/dist/src/init/helper-signing.d.ts +37 -0
- package/dist/src/init/helper-signing.js +67 -0
- package/dist/src/init/helpers-generator.d.ts +87 -0
- package/dist/src/init/helpers-generator.js +1456 -0
- package/dist/src/init/index.d.ts +13 -0
- package/dist/src/init/index.js +15 -0
- package/dist/src/init/mcp-generator.d.ts +26 -0
- package/dist/src/init/mcp-generator.js +126 -0
- package/dist/src/init/memory-package-resolver.d.ts +53 -0
- package/dist/src/init/memory-package-resolver.js +118 -0
- package/dist/src/init/settings-generator.d.ts +14 -0
- package/dist/src/init/settings-generator.js +462 -0
- package/dist/src/init/statusline-generator.d.ts +28 -0
- package/dist/src/init/statusline-generator.js +177 -0
- package/dist/src/init/types.d.ts +331 -0
- package/dist/src/init/types.js +276 -0
- package/dist/src/log-filters.d.ts +46 -0
- package/dist/src/log-filters.js +107 -0
- package/dist/src/mcp-client.d.ts +92 -0
- package/dist/src/mcp-client.js +397 -0
- package/dist/src/mcp-server.d.ts +163 -0
- package/dist/src/mcp-server.js +751 -0
- package/dist/src/mcp-tools/agent-execute-core.d.ts +115 -0
- package/dist/src/mcp-tools/agent-execute-core.js +587 -0
- package/dist/src/mcp-tools/agent-tools.d.ts +9 -0
- package/dist/src/mcp-tools/agent-tools.js +837 -0
- package/dist/src/mcp-tools/agentbbs-tools.d.ts +28 -0
- package/dist/src/mcp-tools/agentbbs-tools.js +394 -0
- package/dist/src/mcp-tools/agentdb-tools.d.ts +35 -0
- package/dist/src/mcp-tools/agentdb-tools.js +1473 -0
- package/dist/src/mcp-tools/agenticow-loader.d.ts +59 -0
- package/dist/src/mcp-tools/agenticow-loader.js +105 -0
- package/dist/src/mcp-tools/agenticow-speculate-tools.d.ts +24 -0
- package/dist/src/mcp-tools/agenticow-speculate-tools.js +209 -0
- package/dist/src/mcp-tools/agenticow-tools.d.ts +36 -0
- package/dist/src/mcp-tools/agenticow-tools.js +360 -0
- package/dist/src/mcp-tools/analyze-tools.d.ts +38 -0
- package/dist/src/mcp-tools/analyze-tools.js +346 -0
- package/dist/src/mcp-tools/auto-install.d.ts +83 -0
- package/dist/src/mcp-tools/auto-install.js +131 -0
- package/dist/src/mcp-tools/autopilot-tools.d.ts +12 -0
- package/dist/src/mcp-tools/autopilot-tools.js +231 -0
- package/dist/src/mcp-tools/browser-intent-tools.d.ts +162 -0
- package/dist/src/mcp-tools/browser-intent-tools.js +548 -0
- package/dist/src/mcp-tools/browser-session-tools.d.ts +27 -0
- package/dist/src/mcp-tools/browser-session-tools.js +398 -0
- package/dist/src/mcp-tools/browser-tools.d.ts +21 -0
- package/dist/src/mcp-tools/browser-tools.js +760 -0
- package/dist/src/mcp-tools/business-pod-tools.d.ts +20 -0
- package/dist/src/mcp-tools/business-pod-tools.js +169 -0
- package/dist/src/mcp-tools/claims-tools.d.ts +12 -0
- package/dist/src/mcp-tools/claims-tools.js +863 -0
- package/dist/src/mcp-tools/config-tools.d.ts +8 -0
- package/dist/src/mcp-tools/config-tools.js +411 -0
- package/dist/src/mcp-tools/coordination-tools.d.ts +13 -0
- package/dist/src/mcp-tools/coordination-tools.js +729 -0
- package/dist/src/mcp-tools/daa-tools.d.ts +13 -0
- package/dist/src/mcp-tools/daa-tools.js +534 -0
- package/dist/src/mcp-tools/embeddings-tools.d.ts +9 -0
- package/dist/src/mcp-tools/embeddings-tools.js +904 -0
- package/dist/src/mcp-tools/github-tools.d.ts +9 -0
- package/dist/src/mcp-tools/github-tools.js +659 -0
- package/dist/src/mcp-tools/guidance-tools.d.ts +15 -0
- package/dist/src/mcp-tools/guidance-tools.js +639 -0
- package/dist/src/mcp-tools/hive-mind-tools.d.ts +8 -0
- package/dist/src/mcp-tools/hive-mind-tools.js +953 -0
- package/dist/src/mcp-tools/hooks-tools.d.ts +65 -0
- package/dist/src/mcp-tools/hooks-tools.js +4836 -0
- package/dist/src/mcp-tools/http-fetch-tools.d.ts +55 -0
- package/dist/src/mcp-tools/http-fetch-tools.js +329 -0
- package/dist/src/mcp-tools/index.d.ts +34 -0
- package/dist/src/mcp-tools/index.js +40 -0
- package/dist/src/mcp-tools/managed-agent-tools.d.ts +22 -0
- package/dist/src/mcp-tools/managed-agent-tools.js +357 -0
- package/dist/src/mcp-tools/memory-tools.d.ts +14 -0
- package/dist/src/mcp-tools/memory-tools.js +1330 -0
- package/dist/src/mcp-tools/metaharness-tools.d.ts +51 -0
- package/dist/src/mcp-tools/metaharness-tools.js +684 -0
- package/dist/src/mcp-tools/neural-tools.d.ts +54 -0
- package/dist/src/mcp-tools/neural-tools.js +1168 -0
- package/dist/src/mcp-tools/performance-tools.d.ts +16 -0
- package/dist/src/mcp-tools/performance-tools.js +675 -0
- package/dist/src/mcp-tools/progress-tools.d.ts +14 -0
- package/dist/src/mcp-tools/progress-tools.js +348 -0
- package/dist/src/mcp-tools/request-tracker.d.ts +17 -0
- package/dist/src/mcp-tools/request-tracker.js +27 -0
- package/dist/src/mcp-tools/ruvllm-tools.d.ts +9 -0
- package/dist/src/mcp-tools/ruvllm-tools.js +355 -0
- package/dist/src/mcp-tools/security-tools.d.ts +18 -0
- package/dist/src/mcp-tools/security-tools.js +556 -0
- package/dist/src/mcp-tools/session-tools.d.ts +8 -0
- package/dist/src/mcp-tools/session-tools.js +517 -0
- package/dist/src/mcp-tools/swarm-tools.d.ts +37 -0
- package/dist/src/mcp-tools/swarm-tools.js +390 -0
- package/dist/src/mcp-tools/system-tools.d.ts +13 -0
- package/dist/src/mcp-tools/system-tools.js +688 -0
- package/dist/src/mcp-tools/task-tools.d.ts +8 -0
- package/dist/src/mcp-tools/task-tools.js +487 -0
- package/dist/src/mcp-tools/terminal-tools.d.ts +8 -0
- package/dist/src/mcp-tools/terminal-tools.js +306 -0
- package/dist/src/mcp-tools/testgen-tools.d.ts +26 -0
- package/dist/src/mcp-tools/testgen-tools.js +168 -0
- package/dist/src/mcp-tools/tool-loop-guardrail.d.ts +31 -0
- package/dist/src/mcp-tools/tool-loop-guardrail.js +71 -0
- package/dist/src/mcp-tools/transfer-tools.d.ts +14 -0
- package/dist/src/mcp-tools/transfer-tools.js +447 -0
- package/dist/src/mcp-tools/types.d.ts +8 -0
- package/dist/src/mcp-tools/types.js +8 -0
- package/dist/src/mcp-tools/validate-input.d.ts +9 -0
- package/dist/src/mcp-tools/validate-input.js +9 -0
- package/dist/src/mcp-tools/wasm-agent-tools.d.ts +13 -0
- package/dist/src/mcp-tools/wasm-agent-tools.js +840 -0
- package/dist/src/mcp-tools/workflow-tools.d.ts +8 -0
- package/dist/src/mcp-tools/workflow-tools.js +884 -0
- package/dist/src/memory/bge-embedder.d.ts +25 -0
- package/dist/src/memory/bge-embedder.js +121 -0
- package/dist/src/memory/cross-encoder-rerank.d.ts +33 -0
- package/dist/src/memory/cross-encoder-rerank.js +123 -0
- package/dist/src/memory/embedding-policy.d.ts +21 -0
- package/dist/src/memory/embedding-policy.js +30 -0
- package/dist/src/memory/embedding-quantization.d.ts +62 -0
- package/dist/src/memory/embedding-quantization.js +156 -0
- package/dist/src/memory/ewc-consolidation.d.ts +305 -0
- package/dist/src/memory/ewc-consolidation.js +611 -0
- package/dist/src/memory/graph-edge-writer.d.ts +95 -0
- package/dist/src/memory/graph-edge-writer.js +217 -0
- package/dist/src/memory/hybrid-retrieval.d.ts +77 -0
- package/dist/src/memory/hybrid-retrieval.js +192 -0
- package/dist/src/memory/intelligence.d.ts +405 -0
- package/dist/src/memory/intelligence.js +1316 -0
- package/dist/src/memory/lucene-bm25.d.ts +19 -0
- package/dist/src/memory/lucene-bm25.js +308 -0
- package/dist/src/memory/memory-bridge.d.ts +537 -0
- package/dist/src/memory/memory-bridge.js +2460 -0
- package/dist/src/memory/memory-initializer.d.ts +556 -0
- package/dist/src/memory/memory-initializer.js +3021 -0
- package/dist/src/memory/neural-package-bridge.d.ts +48 -0
- package/dist/src/memory/neural-package-bridge.js +87 -0
- package/dist/src/memory/rabitq-index.d.ts +60 -0
- package/dist/src/memory/rabitq-index.js +242 -0
- package/dist/src/memory/sona-optimizer.d.ts +267 -0
- package/dist/src/memory/sona-optimizer.js +779 -0
- package/dist/src/memory/structured-distill.d.ts +48 -0
- package/dist/src/memory/structured-distill.js +125 -0
- package/dist/src/output.d.ts +9 -0
- package/dist/src/output.js +9 -0
- package/dist/src/parser.d.ts +89 -0
- package/dist/src/parser.js +516 -0
- package/dist/src/plugins/manager.d.ts +133 -0
- package/dist/src/plugins/manager.js +415 -0
- package/dist/src/plugins/store/discovery.d.ts +99 -0
- package/dist/src/plugins/store/discovery.js +1224 -0
- package/dist/src/plugins/store/index.d.ts +76 -0
- package/dist/src/plugins/store/index.js +141 -0
- package/dist/src/plugins/store/search.d.ts +46 -0
- package/dist/src/plugins/store/search.js +230 -0
- package/dist/src/plugins/store/types.d.ts +279 -0
- package/dist/src/plugins/store/types.js +7 -0
- package/dist/src/plugins/tests/demo-plugin-store.d.ts +7 -0
- package/dist/src/plugins/tests/demo-plugin-store.js +126 -0
- package/dist/src/plugins/tests/standalone-test.d.ts +12 -0
- package/dist/src/plugins/tests/standalone-test.js +188 -0
- package/dist/src/plugins/tests/test-plugin-store.d.ts +7 -0
- package/dist/src/plugins/tests/test-plugin-store.js +206 -0
- package/dist/src/production/circuit-breaker.d.ts +101 -0
- package/dist/src/production/circuit-breaker.js +241 -0
- package/dist/src/production/error-handler.d.ts +92 -0
- package/dist/src/production/error-handler.js +299 -0
- package/dist/src/production/index.d.ts +23 -0
- package/dist/src/production/index.js +18 -0
- package/dist/src/production/monitoring.d.ts +161 -0
- package/dist/src/production/monitoring.js +356 -0
- package/dist/src/production/rate-limiter.d.ts +80 -0
- package/dist/src/production/rate-limiter.js +201 -0
- package/dist/src/production/retry.d.ts +48 -0
- package/dist/src/production/retry.js +179 -0
- package/dist/src/prompt.d.ts +44 -0
- package/dist/src/prompt.js +501 -0
- package/dist/src/proxy/install.d.ts +29 -0
- package/dist/src/proxy/install.js +135 -0
- package/dist/src/proxy/lifecycle.d.ts +61 -0
- package/dist/src/proxy/lifecycle.js +249 -0
- package/dist/src/proxy/paths.d.ts +34 -0
- package/dist/src/proxy/paths.js +70 -0
- package/dist/src/proxy/release.d.ts +47 -0
- package/dist/src/proxy/release.js +138 -0
- package/dist/src/proxy/token-bridge.d.ts +5 -0
- package/dist/src/proxy/token-bridge.js +61 -0
- package/dist/src/proxy/verify.d.ts +44 -0
- package/dist/src/proxy/verify.js +68 -0
- package/dist/src/runtime/headless.d.ts +60 -0
- package/dist/src/runtime/headless.js +284 -0
- package/dist/src/runtime/parent-death-watchdog.d.ts +42 -0
- package/dist/src/runtime/parent-death-watchdog.js +70 -0
- package/dist/src/ruvector/agent-wasm.d.ts +228 -0
- package/dist/src/ruvector/agent-wasm.js +463 -0
- package/dist/src/ruvector/ast-analyzer.d.ts +67 -0
- package/dist/src/ruvector/ast-analyzer.js +277 -0
- package/dist/src/ruvector/codemods/engine.d.ts +45 -0
- package/dist/src/ruvector/codemods/engine.js +291 -0
- package/dist/src/ruvector/codemods/scope-analysis.d.ts +29 -0
- package/dist/src/ruvector/codemods/scope-analysis.js +162 -0
- package/dist/src/ruvector/coverage-router.d.ts +160 -0
- package/dist/src/ruvector/coverage-router.js +531 -0
- package/dist/src/ruvector/coverage-tools.d.ts +33 -0
- package/dist/src/ruvector/coverage-tools.js +157 -0
- package/dist/src/ruvector/diff-classifier.d.ts +175 -0
- package/dist/src/ruvector/diff-classifier.js +699 -0
- package/dist/src/ruvector/diskann-backend.d.ts +78 -0
- package/dist/src/ruvector/diskann-backend.js +310 -0
- package/dist/src/ruvector/enhanced-model-router.d.ts +172 -0
- package/dist/src/ruvector/enhanced-model-router.js +577 -0
- package/dist/src/ruvector/graph-analyzer.d.ts +187 -0
- package/dist/src/ruvector/graph-analyzer.js +929 -0
- package/dist/src/ruvector/graph-backend.d.ts +79 -0
- package/dist/src/ruvector/graph-backend.js +220 -0
- package/dist/src/ruvector/index.d.ts +38 -0
- package/dist/src/ruvector/index.js +86 -0
- package/dist/src/ruvector/lora-adapter.d.ts +292 -0
- package/dist/src/ruvector/lora-adapter.js +710 -0
- package/dist/src/ruvector/model-prices.d.ts +50 -0
- package/dist/src/ruvector/model-prices.js +72 -0
- package/dist/src/ruvector/model-router.d.ts +408 -0
- package/dist/src/ruvector/model-router.js +1162 -0
- package/dist/src/ruvector/neural-router.d.ts +182 -0
- package/dist/src/ruvector/neural-router.js +825 -0
- package/dist/src/ruvector/output-verifier.d.ts +83 -0
- package/dist/src/ruvector/output-verifier.js +277 -0
- package/dist/src/ruvector/q-learning-router.d.ts +227 -0
- package/dist/src/ruvector/q-learning-router.js +721 -0
- package/dist/src/ruvector/router-calibrator.d.ts +65 -0
- package/dist/src/ruvector/router-calibrator.js +120 -0
- package/dist/src/ruvector/router-parallel-recorder.d.ts +127 -0
- package/dist/src/ruvector/router-parallel-recorder.js +183 -0
- package/dist/src/ruvector/router-trajectory.d.ts +194 -0
- package/dist/src/ruvector/router-trajectory.js +281 -0
- package/dist/src/ruvector/run-transcript-recorder.d.ts +154 -0
- package/dist/src/ruvector/run-transcript-recorder.js +209 -0
- package/dist/src/ruvector/ruvllm-wasm.d.ts +179 -0
- package/dist/src/ruvector/ruvllm-wasm.js +379 -0
- package/dist/src/ruvector/semantic-router.d.ts +77 -0
- package/dist/src/ruvector/semantic-router.js +178 -0
- package/dist/src/ruvector/task-embedder.d.ts +56 -0
- package/dist/src/ruvector/task-embedder.js +237 -0
- package/dist/src/ruvector/trajectory-tree.d.ts +113 -0
- package/dist/src/ruvector/trajectory-tree.js +237 -0
- package/dist/src/ruvector/vector-db.d.ts +73 -0
- package/dist/src/ruvector/vector-db.js +301 -0
- package/dist/src/ruvector/wasm-embedder.d.ts +13 -0
- package/dist/src/ruvector/wasm-embedder.js +143 -0
- package/dist/src/security/builtin-aidefence.d.ts +34 -0
- package/dist/src/security/builtin-aidefence.js +86 -0
- package/dist/src/services/agentic-flow-bridge.d.ts +50 -0
- package/dist/src/services/agentic-flow-bridge.js +95 -0
- package/dist/src/services/ai-job-dedup.d.ts +61 -0
- package/dist/src/services/ai-job-dedup.js +136 -0
- package/dist/src/services/checkpoint-gate.d.ts +140 -0
- package/dist/src/services/checkpoint-gate.js +223 -0
- package/dist/src/services/claim-service.d.ts +204 -0
- package/dist/src/services/claim-service.js +818 -0
- package/dist/src/services/config-file-manager.d.ts +37 -0
- package/dist/src/services/config-file-manager.js +224 -0
- package/dist/src/services/container-worker-pool.d.ts +204 -0
- package/dist/src/services/container-worker-pool.js +589 -0
- package/dist/src/services/daemon-autostart.d.ts +17 -0
- package/dist/src/services/daemon-autostart.js +102 -0
- package/dist/src/services/distill-oracle.d.ts +190 -0
- package/dist/src/services/distill-oracle.js +349 -0
- package/dist/src/services/distill-tuning.d.ts +111 -0
- package/dist/src/services/distill-tuning.js +510 -0
- package/dist/src/services/evolve-proof.d.ts +253 -0
- package/dist/src/services/evolve-proof.js +343 -0
- package/dist/src/services/fable-harness.d.ts +208 -0
- package/dist/src/services/fable-harness.js +388 -0
- package/dist/src/services/git-workspace-identity.d.ts +42 -0
- package/dist/src/services/git-workspace-identity.js +99 -0
- package/dist/src/services/global-ai-budget.d.ts +135 -0
- package/dist/src/services/global-ai-budget.js +415 -0
- package/dist/src/services/harness-benchmark.d.ts +68 -0
- package/dist/src/services/harness-benchmark.js +94 -0
- package/dist/src/services/harness-canary.d.ts +60 -0
- package/dist/src/services/harness-canary.js +69 -0
- package/dist/src/services/harness-corpus-harvester.d.ts +51 -0
- package/dist/src/services/harness-corpus-harvester.js +74 -0
- package/dist/src/services/harness-flywheel-generations.d.ts +115 -0
- package/dist/src/services/harness-flywheel-generations.js +360 -0
- package/dist/src/services/harness-flywheel-runtime.d.ts +25 -0
- package/dist/src/services/harness-flywheel-runtime.js +92 -0
- package/dist/src/services/harness-flywheel.d.ts +48 -0
- package/dist/src/services/harness-flywheel.js +207 -0
- package/dist/src/services/harness-frozen-eval.d.ts +22 -0
- package/dist/src/services/harness-frozen-eval.js +66 -0
- package/dist/src/services/harness-hosts.d.ts +40 -0
- package/dist/src/services/harness-hosts.js +88 -0
- package/dist/src/services/harness-improvement-ledger.d.ts +63 -0
- package/dist/src/services/harness-improvement-ledger.js +101 -0
- package/dist/src/services/harness-loop.d.ts +53 -0
- package/dist/src/services/harness-loop.js +85 -0
- package/dist/src/services/harness-qualification.d.ts +66 -0
- package/dist/src/services/harness-qualification.js +143 -0
- package/dist/src/services/harness-replay.d.ts +37 -0
- package/dist/src/services/harness-replay.js +92 -0
- package/dist/src/services/harness-verify.d.ts +33 -0
- package/dist/src/services/harness-verify.js +26 -0
- package/dist/src/services/harness-worker.d.ts +23 -0
- package/dist/src/services/harness-worker.js +66 -0
- package/dist/src/services/headless-worker-executor.d.ts +358 -0
- package/dist/src/services/headless-worker-executor.js +1269 -0
- package/dist/src/services/index.d.ts +13 -0
- package/dist/src/services/index.js +11 -0
- package/dist/src/services/memory-backup.d.ts +53 -0
- package/dist/src/services/memory-backup.js +198 -0
- package/dist/src/services/memory-distillation.d.ts +41 -0
- package/dist/src/services/memory-distillation.js +277 -0
- package/dist/src/services/native-training.d.ts +68 -0
- package/dist/src/services/native-training.js +141 -0
- package/dist/src/services/registry-api.d.ts +58 -0
- package/dist/src/services/registry-api.js +146 -0
- package/dist/src/services/repo-supervisor.d.ts +70 -0
- package/dist/src/services/repo-supervisor.js +228 -0
- package/dist/src/services/ruvector-training.d.ts +222 -0
- package/dist/src/services/ruvector-training.js +693 -0
- package/dist/src/services/swarm-memory-branches.d.ts +135 -0
- package/dist/src/services/swarm-memory-branches.js +213 -0
- package/dist/src/services/weight-eft.d.ts +305 -0
- package/dist/src/services/weight-eft.js +296 -0
- package/dist/src/services/worker-daemon.d.ts +439 -0
- package/dist/src/services/worker-daemon.js +1865 -0
- package/dist/src/services/worker-queue.d.ts +194 -0
- package/dist/src/services/worker-queue.js +513 -0
- package/dist/src/services/workspace-lease.d.ts +55 -0
- package/dist/src/services/workspace-lease.js +191 -0
- package/dist/src/suggest.d.ts +53 -0
- package/dist/src/suggest.js +200 -0
- package/dist/src/transfer/anonymization/index.d.ts +25 -0
- package/dist/src/transfer/anonymization/index.js +175 -0
- package/dist/src/transfer/deploy-seraphine.d.ts +13 -0
- package/dist/src/transfer/deploy-seraphine.js +205 -0
- package/dist/src/transfer/export.d.ts +25 -0
- package/dist/src/transfer/export.js +113 -0
- package/dist/src/transfer/index.d.ts +12 -0
- package/dist/src/transfer/index.js +31 -0
- package/dist/src/transfer/ipfs/client.d.ts +109 -0
- package/dist/src/transfer/ipfs/client.js +307 -0
- package/dist/src/transfer/ipfs/upload.d.ts +95 -0
- package/dist/src/transfer/ipfs/upload.js +413 -0
- package/dist/src/transfer/models/seraphine.d.ts +72 -0
- package/dist/src/transfer/models/seraphine.js +373 -0
- package/dist/src/transfer/serialization/cfp.d.ts +49 -0
- package/dist/src/transfer/serialization/cfp.js +183 -0
- package/dist/src/transfer/storage/gcs.d.ts +82 -0
- package/dist/src/transfer/storage/gcs.js +272 -0
- package/dist/src/transfer/storage/index.d.ts +6 -0
- package/dist/src/transfer/storage/index.js +6 -0
- package/dist/src/transfer/store/discovery.d.ts +84 -0
- package/dist/src/transfer/store/discovery.js +382 -0
- package/dist/src/transfer/store/download.d.ts +70 -0
- package/dist/src/transfer/store/download.js +334 -0
- package/dist/src/transfer/store/index.d.ts +84 -0
- package/dist/src/transfer/store/index.js +153 -0
- package/dist/src/transfer/store/publish.d.ts +76 -0
- package/dist/src/transfer/store/publish.js +294 -0
- package/dist/src/transfer/store/registry.d.ts +58 -0
- package/dist/src/transfer/store/registry.js +285 -0
- package/dist/src/transfer/store/search.d.ts +54 -0
- package/dist/src/transfer/store/search.js +232 -0
- package/dist/src/transfer/store/tests/standalone-test.d.ts +12 -0
- package/dist/src/transfer/store/tests/standalone-test.js +190 -0
- package/dist/src/transfer/store/types.d.ts +193 -0
- package/dist/src/transfer/store/types.js +6 -0
- package/dist/src/transfer/test-seraphine.d.ts +6 -0
- package/dist/src/transfer/test-seraphine.js +105 -0
- package/dist/src/transfer/tests/test-store.d.ts +7 -0
- package/dist/src/transfer/tests/test-store.js +214 -0
- package/dist/src/transfer/types.d.ts +245 -0
- package/dist/src/transfer/types.js +6 -0
- package/dist/src/types.d.ts +13 -0
- package/dist/src/types.js +13 -0
- package/dist/src/update/checker.d.ts +34 -0
- package/dist/src/update/checker.js +191 -0
- package/dist/src/update/executor.d.ts +33 -0
- package/dist/src/update/executor.js +217 -0
- package/dist/src/update/index.d.ts +33 -0
- package/dist/src/update/index.js +64 -0
- package/dist/src/update/rate-limiter.d.ts +20 -0
- package/dist/src/update/rate-limiter.js +96 -0
- package/dist/src/update/validator.d.ts +17 -0
- package/dist/src/update/validator.js +123 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1456 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers Generator
|
|
3
|
+
* Creates utility scripts in .claude/helpers/
|
|
4
|
+
*/
|
|
5
|
+
import { generateStatuslineScript, generateStatuslineHook } from './statusline-generator.js';
|
|
6
|
+
// ADR-127 Phase 4 — attribution is opt-in (#1670 / #2089).
|
|
7
|
+
// When the user passes --attribution (options.attribution === true),
|
|
8
|
+
// this footer is available for injection into generated content such as
|
|
9
|
+
// PR body templates and release notes. It is NEVER hard-wired into the
|
|
10
|
+
// static command-file templates — those are user-owned content.
|
|
11
|
+
export const ATTRIBUTION_FOOTER = '🤖 Generated with [RuFlo](https://github.com/ruvnet/ruflo)';
|
|
12
|
+
/**
|
|
13
|
+
* Detect whether a Claude Code PostToolUse payload represents a FAILED tool run.
|
|
14
|
+
*
|
|
15
|
+
* Why this matters: the learning substrate had 898 feedback records, 100%
|
|
16
|
+
* success, 0 failures — because the post-edit/post-task hooks recorded a
|
|
17
|
+
* hardcoded `success:true` and never inspected the tool outcome. With no
|
|
18
|
+
* negative examples, the oracle tier can't teach good-vs-bad (see the DB
|
|
19
|
+
* analysis + ADR-174). Claude Code passes the tool result in the PostToolUse
|
|
20
|
+
* hook payload (`tool_response`), which for a failed Write/Edit/Bash carries an
|
|
21
|
+
* error marker. This predicate is the single source of truth the generated
|
|
22
|
+
* hook inlines, and is unit-tested here so the detection stays honest.
|
|
23
|
+
*
|
|
24
|
+
* Conservative: returns true only on a POSITIVE error signal; ambiguous/missing
|
|
25
|
+
* payloads default to success (matches prior behavior, avoids false failures).
|
|
26
|
+
*/
|
|
27
|
+
export function isToolFailure(hookInput) {
|
|
28
|
+
if (!hookInput || typeof hookInput !== 'object')
|
|
29
|
+
return false;
|
|
30
|
+
const h = hookInput;
|
|
31
|
+
const tr = (h.tool_response ?? h.toolResponse ?? h.result);
|
|
32
|
+
if (tr == null)
|
|
33
|
+
return false;
|
|
34
|
+
if (typeof tr === 'string') {
|
|
35
|
+
return /\b(error|failed|failure|exception|not found|no such|permission denied|traceback)\b/i.test(tr);
|
|
36
|
+
}
|
|
37
|
+
if (typeof tr === 'object') {
|
|
38
|
+
const o = tr;
|
|
39
|
+
if (o.is_error === true || o.isError === true || o.success === false || o.error != null)
|
|
40
|
+
return true;
|
|
41
|
+
// Bash tool: non-zero exit code is a failure.
|
|
42
|
+
const code = (o.exit_code ?? o.exitCode ?? o.code);
|
|
43
|
+
if (typeof code === 'number' && code !== 0)
|
|
44
|
+
return true;
|
|
45
|
+
// Nested content array (Claude tool result shape): {content:[...], is_error:true}
|
|
46
|
+
if (Array.isArray(o.content) && o.is_error === true)
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// The exact predicate the generated hook inlines — kept in sync with
|
|
52
|
+
// isToolFailure() above (mirrored, since the generated .cjs has no imports).
|
|
53
|
+
const TOOL_FAILURE_EXPR = '(function(hi){' +
|
|
54
|
+
'if(!hi||typeof hi!=="object")return false;' +
|
|
55
|
+
'var tr=hi.tool_response!=null?hi.tool_response:(hi.toolResponse!=null?hi.toolResponse:hi.result);' +
|
|
56
|
+
'if(tr==null)return false;' +
|
|
57
|
+
'if(typeof tr==="string")return /\\b(error|failed|failure|exception|not found|no such|permission denied|traceback)\\b/i.test(tr);' +
|
|
58
|
+
'if(typeof tr==="object"){' +
|
|
59
|
+
'if(tr.is_error===true||tr.isError===true||tr.success===false||tr.error!=null)return true;' +
|
|
60
|
+
'var code=tr.exit_code!=null?tr.exit_code:(tr.exitCode!=null?tr.exitCode:tr.code);' +
|
|
61
|
+
'if(typeof code==="number"&&code!==0)return true;' +
|
|
62
|
+
'if(Array.isArray(tr.content)&&tr.is_error===true)return true;' +
|
|
63
|
+
'}return false;})(hookInput)';
|
|
64
|
+
/**
|
|
65
|
+
* Generate pre-commit hook script
|
|
66
|
+
*/
|
|
67
|
+
export function generatePreCommitHook() {
|
|
68
|
+
return `#!/bin/bash
|
|
69
|
+
# Ruflo Pre-Commit Hook
|
|
70
|
+
# Validates code quality before commit
|
|
71
|
+
|
|
72
|
+
set -e
|
|
73
|
+
|
|
74
|
+
echo "🔍 Running Ruflo pre-commit checks..."
|
|
75
|
+
|
|
76
|
+
# Get staged files
|
|
77
|
+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
78
|
+
|
|
79
|
+
# Run validation for each staged file
|
|
80
|
+
for FILE in $STAGED_FILES; do
|
|
81
|
+
if [[ "$FILE" =~ \\.(ts|js|tsx|jsx)$ ]]; then
|
|
82
|
+
echo " Validating: $FILE"
|
|
83
|
+
npx @claude-flow/cli hooks pre-edit --file "$FILE" --validate-syntax 2>/dev/null || true
|
|
84
|
+
fi
|
|
85
|
+
done
|
|
86
|
+
|
|
87
|
+
# Run tests if available
|
|
88
|
+
if [ -f "package.json" ] && grep -q '"test"' package.json; then
|
|
89
|
+
echo "🧪 Running tests..."
|
|
90
|
+
npm test --if-present 2>/dev/null || echo " Tests skipped or failed"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
echo "✅ Pre-commit checks complete"
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Generate post-commit hook script
|
|
98
|
+
*/
|
|
99
|
+
export function generatePostCommitHook() {
|
|
100
|
+
return `#!/bin/bash
|
|
101
|
+
# Ruflo Post-Commit Hook
|
|
102
|
+
# Records commit metrics and trains patterns
|
|
103
|
+
|
|
104
|
+
COMMIT_HASH=$(git rev-parse HEAD)
|
|
105
|
+
COMMIT_MSG=$(git log -1 --pretty=%B)
|
|
106
|
+
|
|
107
|
+
echo "📊 Recording commit metrics..."
|
|
108
|
+
|
|
109
|
+
# Notify ruflo of commit
|
|
110
|
+
npx ruflo@latest hooks notify \\
|
|
111
|
+
--message "Commit: $COMMIT_MSG" \\
|
|
112
|
+
--level info \\
|
|
113
|
+
--metadata '{"hash": "'$COMMIT_HASH'"}' 2>/dev/null || true
|
|
114
|
+
|
|
115
|
+
echo "✅ Commit recorded"
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Generate session manager script
|
|
120
|
+
*/
|
|
121
|
+
export function generateSessionManager() {
|
|
122
|
+
return `#!/usr/bin/env node
|
|
123
|
+
/**
|
|
124
|
+
* Ruflo Session Manager
|
|
125
|
+
* Handles session lifecycle: start, restore, end
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
const fs = require('fs');
|
|
129
|
+
const path = require('path');
|
|
130
|
+
|
|
131
|
+
const SESSION_DIR = path.join(process.cwd(), '.claude-flow', 'sessions');
|
|
132
|
+
const SESSION_FILE = path.join(SESSION_DIR, 'current.json');
|
|
133
|
+
|
|
134
|
+
const commands = {
|
|
135
|
+
start: () => {
|
|
136
|
+
const sessionId = \`session-\${Date.now()}\`;
|
|
137
|
+
const session = {
|
|
138
|
+
id: sessionId,
|
|
139
|
+
startedAt: new Date().toISOString(),
|
|
140
|
+
cwd: process.cwd(),
|
|
141
|
+
context: {},
|
|
142
|
+
metrics: {
|
|
143
|
+
edits: 0,
|
|
144
|
+
commands: 0,
|
|
145
|
+
tasks: 0,
|
|
146
|
+
errors: 0,
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
fs.mkdirSync(SESSION_DIR, { recursive: true });
|
|
151
|
+
fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
152
|
+
|
|
153
|
+
console.log(\`Session started: \${sessionId}\`);
|
|
154
|
+
return session;
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
restore: () => {
|
|
158
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
159
|
+
console.log('No session to restore');
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
164
|
+
session.restoredAt = new Date().toISOString();
|
|
165
|
+
fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
166
|
+
|
|
167
|
+
console.log(\`Session restored: \${session.id}\`);
|
|
168
|
+
return session;
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
end: () => {
|
|
172
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
173
|
+
console.log('No active session');
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
178
|
+
session.endedAt = new Date().toISOString();
|
|
179
|
+
session.duration = Date.now() - new Date(session.startedAt).getTime();
|
|
180
|
+
|
|
181
|
+
// Archive session
|
|
182
|
+
const archivePath = path.join(SESSION_DIR, \`\${session.id}.json\`);
|
|
183
|
+
fs.writeFileSync(archivePath, JSON.stringify(session, null, 2));
|
|
184
|
+
fs.unlinkSync(SESSION_FILE);
|
|
185
|
+
|
|
186
|
+
console.log(\`Session ended: \${session.id}\`);
|
|
187
|
+
console.log(\`Duration: \${Math.round(session.duration / 1000 / 60)} minutes\`);
|
|
188
|
+
console.log(\`Metrics: \${JSON.stringify(session.metrics)}\`);
|
|
189
|
+
|
|
190
|
+
return session;
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
status: () => {
|
|
194
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
195
|
+
console.log('No active session');
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
200
|
+
const duration = Date.now() - new Date(session.startedAt).getTime();
|
|
201
|
+
|
|
202
|
+
console.log(\`Session: \${session.id}\`);
|
|
203
|
+
console.log(\`Started: \${session.startedAt}\`);
|
|
204
|
+
console.log(\`Duration: \${Math.round(duration / 1000 / 60)} minutes\`);
|
|
205
|
+
console.log(\`Metrics: \${JSON.stringify(session.metrics)}\`);
|
|
206
|
+
|
|
207
|
+
return session;
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
update: (key, value) => {
|
|
211
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
212
|
+
console.log('No active session');
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
217
|
+
session.context[key] = value;
|
|
218
|
+
session.updatedAt = new Date().toISOString();
|
|
219
|
+
fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
220
|
+
|
|
221
|
+
return session;
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
metric: (name) => {
|
|
225
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
230
|
+
if (session.metrics[name] !== undefined) {
|
|
231
|
+
session.metrics[name]++;
|
|
232
|
+
fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return session;
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// CLI
|
|
240
|
+
const [,, command, ...args] = process.argv;
|
|
241
|
+
|
|
242
|
+
if (command && commands[command]) {
|
|
243
|
+
commands[command](...args);
|
|
244
|
+
} else {
|
|
245
|
+
console.log('Usage: session.js <start|restore|end|status|update|metric> [args]');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
module.exports = commands;
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Generate agent router script
|
|
253
|
+
*/
|
|
254
|
+
export function generateAgentRouter() {
|
|
255
|
+
return `#!/usr/bin/env node
|
|
256
|
+
/**
|
|
257
|
+
* Ruflo Agent Router
|
|
258
|
+
*
|
|
259
|
+
* Static keyword router that suggests an agent for a task description.
|
|
260
|
+
* NOTE: This is *not* a learned model. It is a heuristic table; "confidence"
|
|
261
|
+
* is reported as a heuristic prior, not a calibrated probability.
|
|
262
|
+
*
|
|
263
|
+
* #2257 fix: patterns are now word-boundary-anchored so short tokens like
|
|
264
|
+
* \`cd\`, \`ci\`, \`ui\`, \`add\`, \`structure\` no longer match inside unrelated
|
|
265
|
+
* words (\`decision\`, \`infrastructure\`, \`address\`, \`addendum\`). Default
|
|
266
|
+
* matched-confidence dropped from 0.8 to 0.6, and fall-through from 0.5 to
|
|
267
|
+
* 0.3, to reflect that this is a static heuristic, not a learned classifier.
|
|
268
|
+
*/
|
|
269
|
+
|
|
270
|
+
const AGENT_CAPABILITIES = {
|
|
271
|
+
coder: ['code-generation', 'refactoring', 'debugging', 'implementation'],
|
|
272
|
+
tester: ['unit-testing', 'integration-testing', 'coverage', 'test-generation'],
|
|
273
|
+
reviewer: ['code-review', 'security-audit', 'quality-check', 'best-practices'],
|
|
274
|
+
researcher: ['web-search', 'documentation', 'analysis', 'summarization'],
|
|
275
|
+
architect: ['system-design', 'architecture', 'patterns', 'scalability'],
|
|
276
|
+
'backend-dev': ['api', 'database', 'server', 'authentication'],
|
|
277
|
+
'frontend-dev': ['ui', 'react', 'css', 'components'],
|
|
278
|
+
devops: ['ci-cd', 'docker', 'deployment', 'infrastructure'],
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// Each entry has a token list. Single tokens get \\b…\\b boundaries so 'cd'
|
|
282
|
+
// won't match inside 'decide'. Phrases (whitespace or '/') match literally —
|
|
283
|
+
// the whitespace acts as a natural boundary.
|
|
284
|
+
const TASK_PATTERNS = [
|
|
285
|
+
{ tokens: ['implement', 'create', 'build', 'add', 'write code', 'refactor', 'debug'], agent: 'coder' },
|
|
286
|
+
{ tokens: ['test', 'tests', 'spec', 'coverage', 'unit test', 'integration test'], agent: 'tester' },
|
|
287
|
+
{ tokens: ['review', 'audit', 'check', 'validate', 'security'], agent: 'reviewer' },
|
|
288
|
+
{ tokens: ['research', 'find', 'search', 'documentation', 'explore'], agent: 'researcher' },
|
|
289
|
+
{ tokens: ['design', 'architect', 'architecture', 'structure', 'plan'], agent: 'architect' },
|
|
290
|
+
{ tokens: ['api', 'endpoint', 'server', 'backend', 'database'], agent: 'backend-dev' },
|
|
291
|
+
{ tokens: ['ui', 'frontend', 'component', 'react', 'css', 'style'], agent: 'frontend-dev' },
|
|
292
|
+
{ tokens: ['deploy', 'docker', 'ci', 'cd', 'ci/cd', 'pipeline', 'infrastructure', 'devops'], agent: 'devops' },
|
|
293
|
+
];
|
|
294
|
+
|
|
295
|
+
function escapeRegex(s) {
|
|
296
|
+
return s.replace(/[.*+?^\${}()|[\\]\\\\]/g, '\\\\$&');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function buildPattern(tokens) {
|
|
300
|
+
const alternatives = tokens.map((tok) => {
|
|
301
|
+
const escaped = escapeRegex(tok.toLowerCase());
|
|
302
|
+
if (/\\s|\\//.test(tok)) return escaped;
|
|
303
|
+
return \`\\\\b\${escaped}\\\\b\`;
|
|
304
|
+
});
|
|
305
|
+
return new RegExp(\`(?:\${alternatives.join('|')})\`, 'i');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const COMPILED_PATTERNS = TASK_PATTERNS.map((entry) => ({
|
|
309
|
+
agent: entry.agent,
|
|
310
|
+
tokens: entry.tokens,
|
|
311
|
+
regex: buildPattern(entry.tokens),
|
|
312
|
+
}));
|
|
313
|
+
|
|
314
|
+
function routeTask(task) {
|
|
315
|
+
const taskLower = String(task == null ? '' : task).toLowerCase();
|
|
316
|
+
for (const entry of COMPILED_PATTERNS) {
|
|
317
|
+
if (entry.regex.test(taskLower)) {
|
|
318
|
+
return {
|
|
319
|
+
agent: entry.agent,
|
|
320
|
+
confidence: 0.6,
|
|
321
|
+
reason: \`Matched keyword(s) from: \${entry.tokens.join('|')}\`,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
agent: 'coder',
|
|
327
|
+
confidence: 0.3,
|
|
328
|
+
reason: 'Default routing - no specific keyword matched',
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// CLI
|
|
333
|
+
const task = process.argv.slice(2).join(' ');
|
|
334
|
+
|
|
335
|
+
if (task) {
|
|
336
|
+
const result = routeTask(task);
|
|
337
|
+
console.log(JSON.stringify(result, null, 2));
|
|
338
|
+
} else {
|
|
339
|
+
console.log('Usage: router.js <task description>');
|
|
340
|
+
console.log('\\nAvailable agents:', Object.keys(AGENT_CAPABILITIES).join(', '));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
module.exports = { routeTask, AGENT_CAPABILITIES, TASK_PATTERNS, buildPattern };
|
|
344
|
+
`;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Generate memory helper script
|
|
348
|
+
*/
|
|
349
|
+
export function generateMemoryHelper() {
|
|
350
|
+
return `#!/usr/bin/env node
|
|
351
|
+
/**
|
|
352
|
+
* Ruflo Memory Helper
|
|
353
|
+
* Simple key-value memory for cross-session context
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
const fs = require('fs');
|
|
357
|
+
const path = require('path');
|
|
358
|
+
|
|
359
|
+
const MEMORY_DIR = path.join(process.cwd(), '.claude-flow', 'data');
|
|
360
|
+
const MEMORY_FILE = path.join(MEMORY_DIR, 'memory.json');
|
|
361
|
+
|
|
362
|
+
function loadMemory() {
|
|
363
|
+
try {
|
|
364
|
+
if (fs.existsSync(MEMORY_FILE)) {
|
|
365
|
+
return JSON.parse(fs.readFileSync(MEMORY_FILE, 'utf-8'));
|
|
366
|
+
}
|
|
367
|
+
} catch (e) {
|
|
368
|
+
// Ignore
|
|
369
|
+
}
|
|
370
|
+
return {};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function saveMemory(memory) {
|
|
374
|
+
fs.mkdirSync(MEMORY_DIR, { recursive: true });
|
|
375
|
+
fs.writeFileSync(MEMORY_FILE, JSON.stringify(memory, null, 2));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const commands = {
|
|
379
|
+
get: (key) => {
|
|
380
|
+
const memory = loadMemory();
|
|
381
|
+
const value = key ? memory[key] : memory;
|
|
382
|
+
console.log(JSON.stringify(value, null, 2));
|
|
383
|
+
return value;
|
|
384
|
+
},
|
|
385
|
+
|
|
386
|
+
set: (key, value) => {
|
|
387
|
+
if (!key) {
|
|
388
|
+
console.error('Key required');
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
const memory = loadMemory();
|
|
392
|
+
memory[key] = value;
|
|
393
|
+
memory._updated = new Date().toISOString();
|
|
394
|
+
saveMemory(memory);
|
|
395
|
+
console.log(\`Set: \${key}\`);
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
delete: (key) => {
|
|
399
|
+
if (!key) {
|
|
400
|
+
console.error('Key required');
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const memory = loadMemory();
|
|
404
|
+
delete memory[key];
|
|
405
|
+
saveMemory(memory);
|
|
406
|
+
console.log(\`Deleted: \${key}\`);
|
|
407
|
+
},
|
|
408
|
+
|
|
409
|
+
clear: () => {
|
|
410
|
+
saveMemory({});
|
|
411
|
+
console.log('Memory cleared');
|
|
412
|
+
},
|
|
413
|
+
|
|
414
|
+
keys: () => {
|
|
415
|
+
const memory = loadMemory();
|
|
416
|
+
const keys = Object.keys(memory).filter(k => !k.startsWith('_'));
|
|
417
|
+
console.log(keys.join('\\n'));
|
|
418
|
+
return keys;
|
|
419
|
+
},
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// CLI
|
|
423
|
+
const [,, command, key, ...valueParts] = process.argv;
|
|
424
|
+
const value = valueParts.join(' ');
|
|
425
|
+
|
|
426
|
+
if (command && commands[command]) {
|
|
427
|
+
commands[command](key, value);
|
|
428
|
+
} else {
|
|
429
|
+
console.log('Usage: memory.js <get|set|delete|clear|keys> [key] [value]');
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
module.exports = commands;
|
|
433
|
+
`;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Generate hook-handler.cjs (cross-platform hook dispatcher)
|
|
437
|
+
* This is the inline fallback when file copy from the package fails.
|
|
438
|
+
* Uses string concatenation instead of template literals to avoid escaping issues.
|
|
439
|
+
*/
|
|
440
|
+
export function generateHookHandler() {
|
|
441
|
+
// Build as array of lines to avoid template-in-template escaping nightmares
|
|
442
|
+
const lines = [
|
|
443
|
+
'#!/usr/bin/env node',
|
|
444
|
+
'/**',
|
|
445
|
+
' * Ruflo Hook Handler (Cross-Platform)',
|
|
446
|
+
' * Dispatches hook events to the appropriate helper modules.',
|
|
447
|
+
' */',
|
|
448
|
+
'',
|
|
449
|
+
"const path = require('path');",
|
|
450
|
+
"const fs = require('fs');",
|
|
451
|
+
"const os = require('os');",
|
|
452
|
+
"const { spawn } = require('child_process');",
|
|
453
|
+
'',
|
|
454
|
+
'const helpersDir = __dirname;',
|
|
455
|
+
'',
|
|
456
|
+
// #2661-adjacent fix: `refreshRemoteMessages()` (the funnel promo/disclosure
|
|
457
|
+
// pool) is fire-and-forget by design so the statusline's own short-lived
|
|
458
|
+
// per-render subprocess never blocks on a network call — but that also
|
|
459
|
+
// means it NEVER gets a chance to finish there (confirmed live: two
|
|
460
|
+
// consecutive cold-cache statusline renders returned promo:null and no
|
|
461
|
+
// cache file was ever written). `refresh-funnel` exists specifically to
|
|
462
|
+
// be spawned from a longer-lived context; wire that spawn here, once per
|
|
463
|
+
// session, detached so it survives this hook process exiting and isn't
|
|
464
|
+
// awaited so it never adds to the hook's own timeout budget.
|
|
465
|
+
//
|
|
466
|
+
// Deliberately always via npx (--prefer-offline avoids a registry round
|
|
467
|
+
// trip when already cached), never a locally-resolved bin/cli.js path:
|
|
468
|
+
// a fire-and-forget detached spawn has no way to recover if the first
|
|
469
|
+
// candidate is a broken/unbuilt local install (confirmed live — a stale
|
|
470
|
+
// marketplace checkout with a bin/cli.js that exists but throws
|
|
471
|
+
// MODULE_NOT_FOUND on its own dist/ silently ate the spawn with no
|
|
472
|
+
// fallback and no visible error, since stdio is intentionally ignored).
|
|
473
|
+
// npx resolves a real, structurally-valid published package every time.
|
|
474
|
+
'function spawnFunnelRefresh() {',
|
|
475
|
+
' try {',
|
|
476
|
+
" var cmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';",
|
|
477
|
+
" var args = ['--prefer-offline', '@claude-flow/cli', 'hooks', 'refresh-funnel', '--quiet'];",
|
|
478
|
+
' var child = spawn(cmd, args, {',
|
|
479
|
+
" detached: true, stdio: 'ignore', env: Object.assign({}, process.env),",
|
|
480
|
+
' });',
|
|
481
|
+
' child.unref();',
|
|
482
|
+
' } catch (e) { /* best-effort — the statusline\'s own fallback still renders */ }',
|
|
483
|
+
'}',
|
|
484
|
+
'',
|
|
485
|
+
'function safeRequire(modulePath) {',
|
|
486
|
+
' try {',
|
|
487
|
+
' if (fs.existsSync(modulePath)) {',
|
|
488
|
+
' const origLog = console.log;',
|
|
489
|
+
' const origError = console.error;',
|
|
490
|
+
' console.log = () => {};',
|
|
491
|
+
' console.error = () => {};',
|
|
492
|
+
' try {',
|
|
493
|
+
' const mod = require(modulePath);',
|
|
494
|
+
' return mod;',
|
|
495
|
+
' } finally {',
|
|
496
|
+
' console.log = origLog;',
|
|
497
|
+
' console.error = origError;',
|
|
498
|
+
' }',
|
|
499
|
+
' }',
|
|
500
|
+
' } catch (e) {',
|
|
501
|
+
' // silently fail',
|
|
502
|
+
' }',
|
|
503
|
+
' return null;',
|
|
504
|
+
'}',
|
|
505
|
+
'',
|
|
506
|
+
"const router = safeRequire(path.join(helpersDir, 'router.js'));",
|
|
507
|
+
"const session = safeRequire(path.join(helpersDir, 'session.js'));",
|
|
508
|
+
"const memory = safeRequire(path.join(helpersDir, 'memory.js'));",
|
|
509
|
+
"const intelligence = safeRequire(path.join(helpersDir, 'intelligence.cjs'));",
|
|
510
|
+
'',
|
|
511
|
+
'const [,, command, ...args] = process.argv;',
|
|
512
|
+
'',
|
|
513
|
+
'// Read stdin with timeout — Claude Code sends hook data as JSON via stdin.',
|
|
514
|
+
'// Timeout prevents hanging when stdin is in an ambiguous state (not TTY, not pipe).',
|
|
515
|
+
'async function readStdin() {',
|
|
516
|
+
' if (process.stdin.isTTY) return "";',
|
|
517
|
+
' return new Promise((resolve) => {',
|
|
518
|
+
' let data = "";',
|
|
519
|
+
' const timer = setTimeout(() => {',
|
|
520
|
+
' process.stdin.removeAllListeners();',
|
|
521
|
+
' process.stdin.pause();',
|
|
522
|
+
' resolve(data);',
|
|
523
|
+
' }, 500);',
|
|
524
|
+
' process.stdin.setEncoding("utf8");',
|
|
525
|
+
' process.stdin.on("data", (chunk) => { data += chunk; });',
|
|
526
|
+
' process.stdin.on("end", () => { clearTimeout(timer); resolve(data); });',
|
|
527
|
+
' process.stdin.on("error", () => { clearTimeout(timer); resolve(data); });',
|
|
528
|
+
' process.stdin.resume();',
|
|
529
|
+
' });',
|
|
530
|
+
'}',
|
|
531
|
+
'',
|
|
532
|
+
'async function main() {',
|
|
533
|
+
' let stdinData = "";',
|
|
534
|
+
' try { stdinData = await readStdin(); } catch (e) { /* ignore */ }',
|
|
535
|
+
' let hookInput = {};',
|
|
536
|
+
' if (stdinData.trim()) {',
|
|
537
|
+
' try { hookInput = JSON.parse(stdinData); } catch (e) { /* ignore */ }',
|
|
538
|
+
' }',
|
|
539
|
+
' // Prefer stdin fields, then env, then argv. `hookInput.toolInput` is an',
|
|
540
|
+
' // object (e.g. {command:"ls"}); falling back to it directly bound prompt',
|
|
541
|
+
' // to the object and tripped .toLowerCase() / .substring() on every Bash',
|
|
542
|
+
' // hook (#1944). Pull `.command` off whichever stdin shape Claude Code sent.',
|
|
543
|
+
' var toolInputObj = hookInput.toolInput || hookInput.tool_input || {};',
|
|
544
|
+
" var prompt = hookInput.prompt || hookInput.command || toolInputObj.command || process.env.PROMPT || process.env.TOOL_INPUT_command || args.join(' ') || '';",
|
|
545
|
+
' // Capture FAILURES, not just successes, so the learning substrate has',
|
|
546
|
+
' // negative examples (see ADR-174 / DB analysis). Mirrors isToolFailure().',
|
|
547
|
+
' var toolFailed = ' + TOOL_FAILURE_EXPR + ';',
|
|
548
|
+
'',
|
|
549
|
+
'const handlers = {',
|
|
550
|
+
" 'route': () => {",
|
|
551
|
+
' if (intelligence && intelligence.getContext) {',
|
|
552
|
+
' try {',
|
|
553
|
+
' const ctx = intelligence.getContext(prompt);',
|
|
554
|
+
' if (ctx) console.log(ctx);',
|
|
555
|
+
' } catch (e) { /* non-fatal */ }',
|
|
556
|
+
' }',
|
|
557
|
+
' if (router && router.routeTask) {',
|
|
558
|
+
' const result = router.routeTask(prompt);',
|
|
559
|
+
' var output = [];',
|
|
560
|
+
" output.push('[INFO] Routing task: ' + (prompt.substring(0, 80) || '(no prompt)'));",
|
|
561
|
+
" output.push('');",
|
|
562
|
+
" output.push('+------------------- Primary Recommendation -------------------+');",
|
|
563
|
+
" output.push('| Agent: ' + result.agent.padEnd(53) + '|');",
|
|
564
|
+
" output.push('| Confidence: ' + (result.confidence * 100).toFixed(1) + '%' + ' '.repeat(44) + '|');",
|
|
565
|
+
" output.push('| Reason: ' + result.reason.substring(0, 53).padEnd(53) + '|');",
|
|
566
|
+
" output.push('+--------------------------------------------------------------+');",
|
|
567
|
+
" console.log(output.join('\\n'));",
|
|
568
|
+
' } else {',
|
|
569
|
+
" console.log('[INFO] Router not available, using default routing');",
|
|
570
|
+
' }',
|
|
571
|
+
'',
|
|
572
|
+
' // Rate-limit -> sponsored-capacity nudge (ADR-312/313). Fires here,',
|
|
573
|
+
' // client-side, BEFORE the API call this prompt would make - so it',
|
|
574
|
+
' // still reaches the transcript even if that call then fails from the',
|
|
575
|
+
' // rate limit. Cheap local file reads only; never a network call or a',
|
|
576
|
+
' // child process, so it cannot add latency to prompt submission.',
|
|
577
|
+
' try {',
|
|
578
|
+
" var rlFunnelEnv = process.env.RUFLO_FUNNEL;",
|
|
579
|
+
' var rlDisabledByEnv = rlFunnelEnv !== undefined && /^(0|false|off|no)$/i.test(String(rlFunnelEnv).trim());',
|
|
580
|
+
" var rlCiVars = ['CI', 'GITHUB_ACTIONS', 'GITLAB_CI', 'CIRCLECI', 'TRAVIS', 'BUILDKITE', 'JENKINS_URL', 'TEAMCITY_VERSION', 'TF_BUILD'];",
|
|
581
|
+
' var rlIsCi = rlCiVars.some(function (v) {',
|
|
582
|
+
' var val = process.env[v];',
|
|
583
|
+
" return val !== undefined && val !== '' && val !== '0' && String(val).toLowerCase() !== 'false';",
|
|
584
|
+
' });',
|
|
585
|
+
" var rlHome = path.join(os.homedir(), '.ruflo');",
|
|
586
|
+
' var rlUserDisabled = false;',
|
|
587
|
+
' try {',
|
|
588
|
+
" var rlUserCfg = JSON.parse(fs.readFileSync(path.join(rlHome, 'funnel.json'), 'utf8'));",
|
|
589
|
+
' rlUserDisabled = !!(rlUserCfg && rlUserCfg.enabled === false);',
|
|
590
|
+
' } catch (e) { /* absent/malformed = not disabled */ }',
|
|
591
|
+
' var rlProjectDisabled = false;',
|
|
592
|
+
' try {',
|
|
593
|
+
" var rlProjCfg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'claude-flow.config.json'), 'utf8'));",
|
|
594
|
+
' rlProjectDisabled = !!(rlProjCfg && rlProjCfg.funnel && rlProjCfg.funnel.enabled === false);',
|
|
595
|
+
' } catch (e) { /* absent/malformed = not disabled */ }',
|
|
596
|
+
'',
|
|
597
|
+
' if (!rlDisabledByEnv && !rlIsCi && !rlUserDisabled && !rlProjectDisabled) {',
|
|
598
|
+
' var rlStatus = null;',
|
|
599
|
+
" try { rlStatus = JSON.parse(fs.readFileSync(path.join(rlHome, 'rate-limit-status.json'), 'utf8')); } catch (e) { /* not flagged */ }",
|
|
600
|
+
' var rlIsLimited = false;',
|
|
601
|
+
' if (rlStatus && rlStatus.limited) {',
|
|
602
|
+
' if (rlStatus.since) {',
|
|
603
|
+
' var rlSinceMs = Date.parse(rlStatus.since);',
|
|
604
|
+
' rlIsLimited = isNaN(rlSinceMs) ? true : (Date.now() - rlSinceMs) < 6 * 60 * 60 * 1000;',
|
|
605
|
+
' } else {',
|
|
606
|
+
' rlIsLimited = true;',
|
|
607
|
+
' }',
|
|
608
|
+
' }',
|
|
609
|
+
' if (rlIsLimited) {',
|
|
610
|
+
' var rlConsented = false;',
|
|
611
|
+
' try {',
|
|
612
|
+
" var rlConsentFile = JSON.parse(fs.readFileSync(path.join(rlHome, 'consent.json'), 'utf8'));",
|
|
613
|
+
" var rlReceipt = rlConsentFile && rlConsentFile['sponsored-downtime'];",
|
|
614
|
+
' rlConsented = !!(rlReceipt && rlReceipt.granted === true && rlReceipt.at !== null && rlReceipt.policyVersion === 1);',
|
|
615
|
+
' } catch (e) { /* not consented */ }',
|
|
616
|
+
' if (!rlConsented) {',
|
|
617
|
+
" console.log('[COGNITUM] Hit your Claude usage limit? Free sponsored capacity is available at cognitum.one/meta-llm -- run: ruflo proxy sponsor-enable --yes');",
|
|
618
|
+
' }',
|
|
619
|
+
' }',
|
|
620
|
+
' }',
|
|
621
|
+
' } catch (e) { /* nudge must never break the hook */ }',
|
|
622
|
+
' },',
|
|
623
|
+
'',
|
|
624
|
+
" 'pre-bash': () => {",
|
|
625
|
+
' var cmd = prompt.toLowerCase();',
|
|
626
|
+
" var dangerous = ['rm -rf /', 'format c:', 'del /s /q c:\\\\', ':(){:|:&};:'];",
|
|
627
|
+
' for (var i = 0; i < dangerous.length; i++) {',
|
|
628
|
+
' if (cmd.includes(dangerous[i])) {',
|
|
629
|
+
" console.error('[BLOCKED] Dangerous command detected: ' + dangerous[i]);",
|
|
630
|
+
' process.exit(1);',
|
|
631
|
+
' }',
|
|
632
|
+
' }',
|
|
633
|
+
" console.log('[OK] Command validated');",
|
|
634
|
+
' },',
|
|
635
|
+
'',
|
|
636
|
+
" 'post-edit': () => {",
|
|
637
|
+
' if (session && session.metric) {',
|
|
638
|
+
" try { session.metric('edits'); } catch (e) { /* no active session */ }",
|
|
639
|
+
' }',
|
|
640
|
+
' if (intelligence && intelligence.recordEdit) {',
|
|
641
|
+
' try {',
|
|
642
|
+
" var file = process.env.TOOL_INPUT_file_path || args[0] || '';",
|
|
643
|
+
' intelligence.recordEdit(file, !toolFailed);',
|
|
644
|
+
' } catch (e) { /* non-fatal */ }',
|
|
645
|
+
' }',
|
|
646
|
+
" console.log(toolFailed ? '[LEARN] Edit FAILURE recorded' : '[OK] Edit recorded');",
|
|
647
|
+
' },',
|
|
648
|
+
'',
|
|
649
|
+
" 'session-restore': () => {",
|
|
650
|
+
' spawnFunnelRefresh();',
|
|
651
|
+
' if (session) {',
|
|
652
|
+
' var existing = session.restore && session.restore();',
|
|
653
|
+
' if (!existing) {',
|
|
654
|
+
' session.start && session.start();',
|
|
655
|
+
' }',
|
|
656
|
+
' } else {',
|
|
657
|
+
" console.log('[OK] Session restored: session-' + Date.now());",
|
|
658
|
+
' }',
|
|
659
|
+
' if (intelligence && intelligence.init) {',
|
|
660
|
+
' try {',
|
|
661
|
+
' var result = intelligence.init();',
|
|
662
|
+
' if (result && result.nodes > 0) {',
|
|
663
|
+
" console.log('[INTELLIGENCE] Loaded ' + result.nodes + ' patterns, ' + result.edges + ' edges');",
|
|
664
|
+
' }',
|
|
665
|
+
' } catch (e) { /* non-fatal */ }',
|
|
666
|
+
' }',
|
|
667
|
+
' },',
|
|
668
|
+
'',
|
|
669
|
+
" 'session-end': () => {",
|
|
670
|
+
' if (intelligence && intelligence.consolidate) {',
|
|
671
|
+
' try {',
|
|
672
|
+
' var result = intelligence.consolidate();',
|
|
673
|
+
' if (result && result.entries > 0) {',
|
|
674
|
+
" var msg = '[INTELLIGENCE] Consolidated: ' + result.entries + ' entries, ' + result.edges + ' edges';",
|
|
675
|
+
" if (result.newEntries > 0) msg += ', ' + result.newEntries + ' new';",
|
|
676
|
+
" msg += ', PageRank recomputed';",
|
|
677
|
+
' console.log(msg);',
|
|
678
|
+
' }',
|
|
679
|
+
' } catch (e) { /* non-fatal */ }',
|
|
680
|
+
' }',
|
|
681
|
+
' if (session && session.end) {',
|
|
682
|
+
' session.end();',
|
|
683
|
+
' } else {',
|
|
684
|
+
" console.log('[OK] Session ended');",
|
|
685
|
+
' }',
|
|
686
|
+
' },',
|
|
687
|
+
'',
|
|
688
|
+
" 'pre-task': () => {",
|
|
689
|
+
' if (session && session.metric) {',
|
|
690
|
+
" try { session.metric('tasks'); } catch (e) { /* no active session */ }",
|
|
691
|
+
' }',
|
|
692
|
+
' if (router && router.routeTask && prompt) {',
|
|
693
|
+
' var result = router.routeTask(prompt);',
|
|
694
|
+
" console.log('[INFO] Task routed to: ' + result.agent + ' (confidence: ' + result.confidence + ')');",
|
|
695
|
+
' } else {',
|
|
696
|
+
" console.log('[OK] Task started');",
|
|
697
|
+
' }',
|
|
698
|
+
' },',
|
|
699
|
+
'',
|
|
700
|
+
" 'post-task': () => {",
|
|
701
|
+
' if (intelligence && intelligence.feedback) {',
|
|
702
|
+
' try {',
|
|
703
|
+
' intelligence.feedback(!toolFailed);',
|
|
704
|
+
' } catch (e) { /* non-fatal */ }',
|
|
705
|
+
' }',
|
|
706
|
+
" console.log(toolFailed ? '[LEARN] Task FAILURE recorded' : '[OK] Task completed');",
|
|
707
|
+
' },',
|
|
708
|
+
'',
|
|
709
|
+
" 'compact-manual': () => {",
|
|
710
|
+
" console.log('PreCompact Guidance:');",
|
|
711
|
+
" console.log('IMPORTANT: Review CLAUDE.md in project root for:');",
|
|
712
|
+
" console.log(' - Available agents and concurrent usage patterns');",
|
|
713
|
+
" console.log(' - Swarm coordination strategies (hierarchical, mesh, adaptive)');",
|
|
714
|
+
" console.log(' - Critical concurrent execution rules (1 MESSAGE = ALL OPERATIONS)');",
|
|
715
|
+
" console.log('Ready for compact operation');",
|
|
716
|
+
' },',
|
|
717
|
+
'',
|
|
718
|
+
" 'compact-auto': () => {",
|
|
719
|
+
" console.log('Auto-Compact Guidance (Context Window Full):');",
|
|
720
|
+
" console.log('CRITICAL: Before compacting, ensure you understand:');",
|
|
721
|
+
" console.log(' - All agents available in .claude/agents/ directory');",
|
|
722
|
+
" console.log(' - Concurrent execution patterns from CLAUDE.md');",
|
|
723
|
+
" console.log(' - Swarm coordination strategies for complex tasks');",
|
|
724
|
+
" console.log('Apply GOLDEN RULE: Always batch operations in single messages');",
|
|
725
|
+
" console.log('Auto-compact proceeding with full agent context');",
|
|
726
|
+
' },',
|
|
727
|
+
'',
|
|
728
|
+
" 'status': () => {",
|
|
729
|
+
" console.log('[OK] Status check');",
|
|
730
|
+
' },',
|
|
731
|
+
'',
|
|
732
|
+
" 'stats': () => {",
|
|
733
|
+
' if (intelligence && intelligence.stats) {',
|
|
734
|
+
" intelligence.stats(args.includes('--json'));",
|
|
735
|
+
' } else {',
|
|
736
|
+
" console.log('[WARN] Intelligence module not available. Run session-restore first.');",
|
|
737
|
+
' }',
|
|
738
|
+
' },',
|
|
739
|
+
'};',
|
|
740
|
+
'',
|
|
741
|
+
'if (command && handlers[command]) {',
|
|
742
|
+
' try {',
|
|
743
|
+
' handlers[command]();',
|
|
744
|
+
' } catch (e) {',
|
|
745
|
+
" console.log('[WARN] Hook ' + command + ' encountered an error: ' + e.message);",
|
|
746
|
+
' }',
|
|
747
|
+
'} else if (command) {',
|
|
748
|
+
" console.log('[OK] Hook: ' + command);",
|
|
749
|
+
'} else {',
|
|
750
|
+
" console.log('Usage: hook-handler.cjs <route|pre-bash|post-edit|session-restore|session-end|pre-task|post-task|compact-manual|compact-auto|status|stats>');",
|
|
751
|
+
'}',
|
|
752
|
+
'} // end main',
|
|
753
|
+
'',
|
|
754
|
+
'process.exitCode = 0;',
|
|
755
|
+
'main().catch(() => {}).finally(() => { process.exit(0); });',
|
|
756
|
+
];
|
|
757
|
+
return lines.join('\n') + '\n';
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Generate a minimal intelligence.cjs stub for fallback installs.
|
|
761
|
+
* Provides the same API as the full intelligence.cjs but with simplified logic.
|
|
762
|
+
* Gets overwritten when source copy succeeds (full version has PageRank, Jaccard, etc.)
|
|
763
|
+
*/
|
|
764
|
+
export function generateIntelligenceStub() {
|
|
765
|
+
const lines = [
|
|
766
|
+
'#!/usr/bin/env node',
|
|
767
|
+
'/**',
|
|
768
|
+
' * Intelligence Layer Stub (ADR-050)',
|
|
769
|
+
' * Minimal fallback — full version is copied from package source.',
|
|
770
|
+
' * Provides: init, getContext, recordEdit, feedback, consolidate',
|
|
771
|
+
' */',
|
|
772
|
+
"'use strict';",
|
|
773
|
+
'',
|
|
774
|
+
"const fs = require('fs');",
|
|
775
|
+
"const path = require('path');",
|
|
776
|
+
"const os = require('os');",
|
|
777
|
+
'',
|
|
778
|
+
"const DATA_DIR = path.join(process.cwd(), '.claude-flow', 'data');",
|
|
779
|
+
"const STORE_PATH = path.join(DATA_DIR, 'auto-memory-store.json');",
|
|
780
|
+
"const RANKED_PATH = path.join(DATA_DIR, 'ranked-context.json');",
|
|
781
|
+
"const PENDING_PATH = path.join(DATA_DIR, 'pending-insights.jsonl');",
|
|
782
|
+
"const SESSION_DIR = path.join(process.cwd(), '.claude-flow', 'sessions');",
|
|
783
|
+
"const SESSION_FILE = path.join(SESSION_DIR, 'current.json');",
|
|
784
|
+
'',
|
|
785
|
+
'function ensureDir(dir) {',
|
|
786
|
+
' if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });',
|
|
787
|
+
'}',
|
|
788
|
+
'',
|
|
789
|
+
'function readJSON(p) {',
|
|
790
|
+
' try { return fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, "utf-8")) : null; }',
|
|
791
|
+
' catch { return null; }',
|
|
792
|
+
'}',
|
|
793
|
+
'',
|
|
794
|
+
'function writeJSON(p, data) {',
|
|
795
|
+
' ensureDir(path.dirname(p));',
|
|
796
|
+
' fs.writeFileSync(p, JSON.stringify(data, null, 2), "utf-8");',
|
|
797
|
+
'}',
|
|
798
|
+
'',
|
|
799
|
+
'// Read session context key',
|
|
800
|
+
'function sessionGet(key) {',
|
|
801
|
+
' var session = readJSON(SESSION_FILE);',
|
|
802
|
+
' if (!session) return null;',
|
|
803
|
+
' return key ? (session.context || {})[key] : session.context;',
|
|
804
|
+
'}',
|
|
805
|
+
'',
|
|
806
|
+
'// Write session context key',
|
|
807
|
+
'function sessionSet(key, value) {',
|
|
808
|
+
' var session = readJSON(SESSION_FILE);',
|
|
809
|
+
' if (!session) return;',
|
|
810
|
+
' if (!session.context) session.context = {};',
|
|
811
|
+
' session.context[key] = value;',
|
|
812
|
+
' writeJSON(SESSION_FILE, session);',
|
|
813
|
+
'}',
|
|
814
|
+
'',
|
|
815
|
+
'// Tokenize text into words',
|
|
816
|
+
'function tokenize(text) {',
|
|
817
|
+
' if (!text) return [];',
|
|
818
|
+
' return text.toLowerCase().replace(/[^a-z0-9\\s]/g, " ").split(/\\s+/).filter(function(w) { return w.length > 2; });',
|
|
819
|
+
'}',
|
|
820
|
+
'',
|
|
821
|
+
'// Bootstrap entries from MEMORY.md files when store is empty',
|
|
822
|
+
'function bootstrapFromMemoryFiles() {',
|
|
823
|
+
' var entries = [];',
|
|
824
|
+
' var candidates = [',
|
|
825
|
+
' path.join(os.homedir(), ".claude", "projects"),',
|
|
826
|
+
' path.join(process.cwd(), ".claude-flow", "memory"),',
|
|
827
|
+
' path.join(process.cwd(), ".claude", "memory"),',
|
|
828
|
+
' ];',
|
|
829
|
+
' for (var i = 0; i < candidates.length; i++) {',
|
|
830
|
+
' try {',
|
|
831
|
+
' if (!fs.existsSync(candidates[i])) continue;',
|
|
832
|
+
' var files = [];',
|
|
833
|
+
' try {',
|
|
834
|
+
' var items = fs.readdirSync(candidates[i], { withFileTypes: true, recursive: true });',
|
|
835
|
+
' for (var j = 0; j < items.length; j++) {',
|
|
836
|
+
' if (items[j].name === "MEMORY.md") {',
|
|
837
|
+
' var parentDir = items[j].parentPath || items[j].path || candidates[i];',
|
|
838
|
+
' var fp = path.join(parentDir, items[j].name);',
|
|
839
|
+
' files.push(fp);',
|
|
840
|
+
' }',
|
|
841
|
+
' }',
|
|
842
|
+
' } catch (e) { continue; }',
|
|
843
|
+
' for (var k = 0; k < files.length; k++) {',
|
|
844
|
+
' try {',
|
|
845
|
+
' var content = fs.readFileSync(files[k], "utf-8");',
|
|
846
|
+
' var sections = content.split(/^##\\s+/m).filter(function(s) { return s.trim().length > 20; });',
|
|
847
|
+
' for (var s = 0; s < sections.length; s++) {',
|
|
848
|
+
' var lines2 = sections[s].split("\\n");',
|
|
849
|
+
' var title = lines2[0] ? lines2[0].trim() : "section-" + s;',
|
|
850
|
+
' entries.push({',
|
|
851
|
+
' id: "mem-" + entries.length,',
|
|
852
|
+
' content: sections[s].substring(0, 500),',
|
|
853
|
+
' summary: title.substring(0, 100),',
|
|
854
|
+
' category: "memory",',
|
|
855
|
+
' confidence: 0.5,',
|
|
856
|
+
' sourceFile: files[k],',
|
|
857
|
+
' words: tokenize(sections[s].substring(0, 500)),',
|
|
858
|
+
' });',
|
|
859
|
+
' }',
|
|
860
|
+
' } catch (e) { /* skip */ }',
|
|
861
|
+
' }',
|
|
862
|
+
' } catch (e) { /* skip */ }',
|
|
863
|
+
' }',
|
|
864
|
+
' return entries;',
|
|
865
|
+
'}',
|
|
866
|
+
'',
|
|
867
|
+
'// Load entries from auto-memory-store or bootstrap from MEMORY.md',
|
|
868
|
+
'function loadEntries() {',
|
|
869
|
+
' var store = readJSON(STORE_PATH);',
|
|
870
|
+
' // Support both formats: flat array or { entries: [...] }',
|
|
871
|
+
' var entries = null;',
|
|
872
|
+
' if (store) {',
|
|
873
|
+
' if (Array.isArray(store) && store.length > 0) {',
|
|
874
|
+
' entries = store;',
|
|
875
|
+
' } else if (store.entries && store.entries.length > 0) {',
|
|
876
|
+
' entries = store.entries;',
|
|
877
|
+
' }',
|
|
878
|
+
' }',
|
|
879
|
+
' if (entries) {',
|
|
880
|
+
' return entries.map(function(e, i) {',
|
|
881
|
+
' return {',
|
|
882
|
+
' id: e.id || ("entry-" + i),',
|
|
883
|
+
' content: e.content || e.value || "",',
|
|
884
|
+
' summary: e.summary || e.key || "",',
|
|
885
|
+
' category: e.category || e.namespace || "default",',
|
|
886
|
+
' confidence: e.confidence || 0.5,',
|
|
887
|
+
' sourceFile: e.sourceFile || (e.metadata && e.metadata.sourceFile) || "",',
|
|
888
|
+
' words: tokenize((e.content || e.value || "") + " " + (e.summary || e.key || "")),',
|
|
889
|
+
' };',
|
|
890
|
+
' });',
|
|
891
|
+
' }',
|
|
892
|
+
' return bootstrapFromMemoryFiles();',
|
|
893
|
+
'}',
|
|
894
|
+
'',
|
|
895
|
+
'// Simple keyword match score',
|
|
896
|
+
'function matchScore(promptWords, entryWords) {',
|
|
897
|
+
' if (!promptWords.length || !entryWords.length) return 0;',
|
|
898
|
+
' var entrySet = {};',
|
|
899
|
+
' for (var i = 0; i < entryWords.length; i++) entrySet[entryWords[i]] = true;',
|
|
900
|
+
' var overlap = 0;',
|
|
901
|
+
' for (var j = 0; j < promptWords.length; j++) {',
|
|
902
|
+
' if (entrySet[promptWords[j]]) overlap++;',
|
|
903
|
+
' }',
|
|
904
|
+
' var union = Object.keys(entrySet).length + promptWords.length - overlap;',
|
|
905
|
+
' return union > 0 ? overlap / union : 0;',
|
|
906
|
+
'}',
|
|
907
|
+
'',
|
|
908
|
+
'var cachedEntries = null;',
|
|
909
|
+
'',
|
|
910
|
+
'module.exports = {',
|
|
911
|
+
' init: function() {',
|
|
912
|
+
' cachedEntries = loadEntries();',
|
|
913
|
+
' var ranked = cachedEntries.map(function(e) {',
|
|
914
|
+
' return { id: e.id, content: e.content, summary: e.summary, category: e.category, confidence: e.confidence, words: e.words };',
|
|
915
|
+
' });',
|
|
916
|
+
' writeJSON(RANKED_PATH, { version: 1, computedAt: Date.now(), entries: ranked });',
|
|
917
|
+
' return { nodes: cachedEntries.length, edges: 0 };',
|
|
918
|
+
' },',
|
|
919
|
+
'',
|
|
920
|
+
' getContext: function(prompt) {',
|
|
921
|
+
' if (!prompt) return null;',
|
|
922
|
+
' var ranked = readJSON(RANKED_PATH);',
|
|
923
|
+
' var entries = (ranked && ranked.entries) || (cachedEntries || []);',
|
|
924
|
+
' if (!entries.length) return null;',
|
|
925
|
+
' var promptWords = tokenize(prompt);',
|
|
926
|
+
' if (!promptWords.length) return null;',
|
|
927
|
+
' var scored = entries.map(function(e) {',
|
|
928
|
+
' return { entry: e, score: matchScore(promptWords, e.words || tokenize(e.content + " " + e.summary)) };',
|
|
929
|
+
' }).filter(function(s) { return s.score > 0.05; });',
|
|
930
|
+
' scored.sort(function(a, b) { return b.score - a.score; });',
|
|
931
|
+
' var top = scored.slice(0, 5);',
|
|
932
|
+
' if (!top.length) return null;',
|
|
933
|
+
' var prevMatched = sessionGet("lastMatchedPatterns");',
|
|
934
|
+
' var matchedIds = top.map(function(s) { return s.entry.id; });',
|
|
935
|
+
' sessionSet("lastMatchedPatterns", matchedIds);',
|
|
936
|
+
' if (prevMatched && Array.isArray(prevMatched)) {',
|
|
937
|
+
' var newSet = {};',
|
|
938
|
+
' for (var i = 0; i < matchedIds.length; i++) newSet[matchedIds[i]] = true;',
|
|
939
|
+
' }',
|
|
940
|
+
' var lines2 = ["[INTELLIGENCE] Relevant patterns for this task:"];',
|
|
941
|
+
' for (var j = 0; j < top.length; j++) {',
|
|
942
|
+
' var e = top[j];',
|
|
943
|
+
' var conf = e.entry.confidence || 0.5;',
|
|
944
|
+
' var summary = (e.entry.summary || e.entry.content || "").substring(0, 80);',
|
|
945
|
+
' lines2.push(" * (" + conf.toFixed(2) + ") " + summary);',
|
|
946
|
+
' }',
|
|
947
|
+
' return lines2.join("\\n");',
|
|
948
|
+
' },',
|
|
949
|
+
'',
|
|
950
|
+
' recordEdit: function(file, success) {',
|
|
951
|
+
' if (!file) return;',
|
|
952
|
+
' ensureDir(DATA_DIR);',
|
|
953
|
+
' // success defaults to true; an explicit false (failed edit) is recorded',
|
|
954
|
+
' // so consolidation/distillation gets a negative example (ADR-174).',
|
|
955
|
+
' var line = JSON.stringify({ type: "edit", file: file, success: success !== false, timestamp: Date.now() }) + "\\n";',
|
|
956
|
+
' fs.appendFileSync(PENDING_PATH, line, "utf-8");',
|
|
957
|
+
' },',
|
|
958
|
+
'',
|
|
959
|
+
' feedback: function(success) {',
|
|
960
|
+
' // Stub: no-op in minimal version',
|
|
961
|
+
' },',
|
|
962
|
+
'',
|
|
963
|
+
' consolidate: function() {',
|
|
964
|
+
' var count = 0;',
|
|
965
|
+
' if (fs.existsSync(PENDING_PATH)) {',
|
|
966
|
+
' try {',
|
|
967
|
+
' var content = fs.readFileSync(PENDING_PATH, "utf-8").trim();',
|
|
968
|
+
' count = content ? content.split("\\n").length : 0;',
|
|
969
|
+
' fs.writeFileSync(PENDING_PATH, "", "utf-8");',
|
|
970
|
+
' } catch (e) { /* skip */ }',
|
|
971
|
+
' }',
|
|
972
|
+
' return { entries: count, edges: 0, newEntries: 0 };',
|
|
973
|
+
' },',
|
|
974
|
+
'};',
|
|
975
|
+
];
|
|
976
|
+
return lines.join('\n') + '\n';
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Generate a minimal auto-memory-hook.mjs fallback for fresh installs.
|
|
980
|
+
* This ESM script handles import/sync/status commands gracefully when
|
|
981
|
+
* @claude-flow/memory is not installed. Gets overwritten when source copy succeeds.
|
|
982
|
+
*/
|
|
983
|
+
export function generateAutoMemoryHook() {
|
|
984
|
+
return `#!/usr/bin/env node
|
|
985
|
+
/**
|
|
986
|
+
* Auto Memory Bridge Hook (ADR-048/049) — Minimal Fallback
|
|
987
|
+
* Full version is copied from package source when available.
|
|
988
|
+
*
|
|
989
|
+
* Usage:
|
|
990
|
+
* node auto-memory-hook.mjs import # SessionStart
|
|
991
|
+
* node auto-memory-hook.mjs sync # SessionEnd / Stop
|
|
992
|
+
* node auto-memory-hook.mjs status # Show bridge status
|
|
993
|
+
*/
|
|
994
|
+
|
|
995
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
996
|
+
import { join, dirname } from 'path';
|
|
997
|
+
import { fileURLToPath } from 'url';
|
|
998
|
+
|
|
999
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
1000
|
+
const __dirname = dirname(__filename);
|
|
1001
|
+
const PROJECT_ROOT = join(__dirname, '../..');
|
|
1002
|
+
const DATA_DIR = join(PROJECT_ROOT, '.claude-flow', 'data');
|
|
1003
|
+
const STORE_PATH = join(DATA_DIR, 'auto-memory-store.json');
|
|
1004
|
+
|
|
1005
|
+
const DIM = '\\x1b[2m';
|
|
1006
|
+
const YELLOW = '\\x1b[0;33m';
|
|
1007
|
+
const RESET = '\\x1b[0m';
|
|
1008
|
+
const dim = (msg) => console.log(\` \${DIM}\${msg}\${RESET}\`);
|
|
1009
|
+
|
|
1010
|
+
// #2545: fail LOUD instead of a silent dim skip when @claude-flow/memory is
|
|
1011
|
+
// unresolvable — self-learning imports are a no-op and the user must be told.
|
|
1012
|
+
function warnMemoryUnavailable() {
|
|
1013
|
+
const l1 = \`[AutoMemory] @claude-flow/memory not resolvable from \${PROJECT_ROOT} — self-learning imports are DISABLED.\`;
|
|
1014
|
+
const l2 = ' Fix: npm i -D @claude-flow/memory (or re-run: npx ruflo@latest init, then npx ruflo@latest doctor --fix)';
|
|
1015
|
+
console.log(\`\${YELLOW}\${l1}\${RESET}\`);
|
|
1016
|
+
console.log(\`\${YELLOW}\${l2}\${RESET}\`);
|
|
1017
|
+
process.stderr.write(\`\${l1}\\n\${l2}\\n\`);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// Ensure data dir
|
|
1021
|
+
if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR, { recursive: true });
|
|
1022
|
+
|
|
1023
|
+
async function loadMemoryPackage() {
|
|
1024
|
+
// Strategy 0 (#2545): sidecar recorded by \`init\` / \`doctor --fix\`. On the npx
|
|
1025
|
+
// path @claude-flow/memory lands in the npx cache (unreachable by walk-up), so
|
|
1026
|
+
// init records its absolute path here — the only strategy that works there.
|
|
1027
|
+
try {
|
|
1028
|
+
const sidecar = join(PROJECT_ROOT, '.claude-flow', 'memory-package.json');
|
|
1029
|
+
if (existsSync(sidecar)) {
|
|
1030
|
+
const rec = JSON.parse(readFileSync(sidecar, 'utf-8'));
|
|
1031
|
+
if (rec && rec.distPath && existsSync(rec.distPath)) {
|
|
1032
|
+
return await import(\`file://\${rec.distPath}\`);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
} catch { /* fall through */ }
|
|
1036
|
+
|
|
1037
|
+
// Strategy 1: Use createRequire for CJS-style resolution (handles nested node_modules
|
|
1038
|
+
// when installed as a transitive dependency via npx ruflo / npx claude-flow)
|
|
1039
|
+
try {
|
|
1040
|
+
const { createRequire } = await import('module');
|
|
1041
|
+
const require = createRequire(join(PROJECT_ROOT, 'package.json'));
|
|
1042
|
+
return require('@claude-flow/memory');
|
|
1043
|
+
} catch { /* fall through */ }
|
|
1044
|
+
|
|
1045
|
+
// Strategy 2: ESM import (works when @claude-flow/memory is a direct dependency)
|
|
1046
|
+
try { return await import('@claude-flow/memory'); } catch { /* fall through */ }
|
|
1047
|
+
|
|
1048
|
+
// Strategy 3: Walk up from PROJECT_ROOT looking for the package in any node_modules
|
|
1049
|
+
let searchDir = PROJECT_ROOT;
|
|
1050
|
+
const { parse } = await import('path');
|
|
1051
|
+
while (searchDir !== parse(searchDir).root) {
|
|
1052
|
+
const candidate = join(searchDir, 'node_modules', '@claude-flow', 'memory', 'dist', 'index.js');
|
|
1053
|
+
if (existsSync(candidate)) {
|
|
1054
|
+
try { return await import(\`file://\${candidate}\`); } catch { /* fall through */ }
|
|
1055
|
+
}
|
|
1056
|
+
searchDir = dirname(searchDir);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
return null;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
async function doImport() {
|
|
1063
|
+
const memPkg = await loadMemoryPackage();
|
|
1064
|
+
|
|
1065
|
+
if (!memPkg || !memPkg.AutoMemoryBridge) {
|
|
1066
|
+
warnMemoryUnavailable();
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// Full implementation deferred to copied version
|
|
1071
|
+
dim('Auto memory import available — run init --upgrade for full support');
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
async function doSync() {
|
|
1075
|
+
if (!existsSync(STORE_PATH)) {
|
|
1076
|
+
dim('No entries to sync');
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
const memPkg = await loadMemoryPackage();
|
|
1081
|
+
|
|
1082
|
+
if (!memPkg || !memPkg.AutoMemoryBridge) {
|
|
1083
|
+
warnMemoryUnavailable();
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
dim('Auto memory sync available — run init --upgrade for full support');
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
function doStatus() {
|
|
1091
|
+
console.log('\\n=== Auto Memory Bridge Status ===\\n');
|
|
1092
|
+
console.log(' Package: Fallback mode (run init --upgrade for full)');
|
|
1093
|
+
console.log(\` Store: \${existsSync(STORE_PATH) ? 'Initialized' : 'Not initialized'}\`);
|
|
1094
|
+
console.log('');
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// Suppress unhandled rejection warnings from dynamic import() failures
|
|
1098
|
+
process.on('unhandledRejection', () => {});
|
|
1099
|
+
|
|
1100
|
+
const command = process.argv[2] || 'status';
|
|
1101
|
+
|
|
1102
|
+
try {
|
|
1103
|
+
switch (command) {
|
|
1104
|
+
case 'import': await doImport(); break;
|
|
1105
|
+
case 'sync': await doSync(); break;
|
|
1106
|
+
case 'status': doStatus(); break;
|
|
1107
|
+
default:
|
|
1108
|
+
console.log('Usage: auto-memory-hook.mjs <import|sync|status>');
|
|
1109
|
+
process.exit(1);
|
|
1110
|
+
}
|
|
1111
|
+
} catch (err) {
|
|
1112
|
+
// Hooks must never crash Claude Code - fail silently
|
|
1113
|
+
dim(\`Error (non-critical): \${err.message}\`);
|
|
1114
|
+
}
|
|
1115
|
+
// Ensure clean exit for Claude Code hooks (exit 0 = success)
|
|
1116
|
+
process.exit(0);
|
|
1117
|
+
`;
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Generate Windows PowerShell daemon manager
|
|
1121
|
+
*/
|
|
1122
|
+
export function generateWindowsDaemonManager() {
|
|
1123
|
+
return `# RuFlo V3 Daemon Manager for Windows
|
|
1124
|
+
# PowerShell script for managing background processes
|
|
1125
|
+
|
|
1126
|
+
param(
|
|
1127
|
+
[Parameter(Position=0)]
|
|
1128
|
+
[ValidateSet('start', 'stop', 'status', 'restart')]
|
|
1129
|
+
[string]$Action = 'status'
|
|
1130
|
+
)
|
|
1131
|
+
|
|
1132
|
+
$ErrorActionPreference = 'SilentlyContinue'
|
|
1133
|
+
$ClaudeFlowDir = Join-Path $PWD '.claude-flow'
|
|
1134
|
+
$PidDir = Join-Path $ClaudeFlowDir 'pids'
|
|
1135
|
+
|
|
1136
|
+
# Ensure directories exist
|
|
1137
|
+
if (-not (Test-Path $PidDir)) {
|
|
1138
|
+
New-Item -ItemType Directory -Path $PidDir -Force | Out-Null
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
function Get-DaemonStatus {
|
|
1142
|
+
param([string]$Name, [string]$PidFile)
|
|
1143
|
+
|
|
1144
|
+
if (Test-Path $PidFile) {
|
|
1145
|
+
$pid = Get-Content $PidFile
|
|
1146
|
+
$process = Get-Process -Id $pid -ErrorAction SilentlyContinue
|
|
1147
|
+
if ($process) {
|
|
1148
|
+
return @{ Running = $true; Pid = $pid }
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return @{ Running = $false; Pid = $null }
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
function Start-SwarmMonitor {
|
|
1155
|
+
$pidFile = Join-Path $PidDir 'swarm-monitor.pid'
|
|
1156
|
+
$status = Get-DaemonStatus -Name 'swarm-monitor' -PidFile $pidFile
|
|
1157
|
+
|
|
1158
|
+
if ($status.Running) {
|
|
1159
|
+
Write-Host "Swarm monitor already running (PID: $($status.Pid))" -ForegroundColor Yellow
|
|
1160
|
+
return
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
Write-Host "Starting swarm monitor..." -ForegroundColor Cyan
|
|
1164
|
+
$process = Start-Process -FilePath 'node' -ArgumentList @(
|
|
1165
|
+
'-e',
|
|
1166
|
+
'setInterval(() => { require("fs").writeFileSync(".claude-flow/metrics/swarm-activity.json", JSON.stringify({swarm:{active:true,agent_count:0},timestamp:Date.now()})) }, 5000)'
|
|
1167
|
+
) -PassThru -WindowStyle Hidden
|
|
1168
|
+
|
|
1169
|
+
$process.Id | Out-File $pidFile
|
|
1170
|
+
Write-Host "Swarm monitor started (PID: $($process.Id))" -ForegroundColor Green
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
function Stop-SwarmMonitor {
|
|
1174
|
+
$pidFile = Join-Path $PidDir 'swarm-monitor.pid'
|
|
1175
|
+
$status = Get-DaemonStatus -Name 'swarm-monitor' -PidFile $pidFile
|
|
1176
|
+
|
|
1177
|
+
if (-not $status.Running) {
|
|
1178
|
+
Write-Host "Swarm monitor not running" -ForegroundColor Yellow
|
|
1179
|
+
return
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
Stop-Process -Id $status.Pid -Force
|
|
1183
|
+
Remove-Item $pidFile -Force
|
|
1184
|
+
Write-Host "Swarm monitor stopped" -ForegroundColor Green
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
function Show-Status {
|
|
1188
|
+
Write-Host ""
|
|
1189
|
+
Write-Host "RuFlo V3 Daemon Status" -ForegroundColor Cyan
|
|
1190
|
+
Write-Host "=============================" -ForegroundColor Cyan
|
|
1191
|
+
|
|
1192
|
+
$swarmPid = Join-Path $PidDir 'swarm-monitor.pid'
|
|
1193
|
+
$swarmStatus = Get-DaemonStatus -Name 'swarm-monitor' -PidFile $swarmPid
|
|
1194
|
+
|
|
1195
|
+
if ($swarmStatus.Running) {
|
|
1196
|
+
Write-Host " Swarm Monitor: RUNNING (PID: $($swarmStatus.Pid))" -ForegroundColor Green
|
|
1197
|
+
} else {
|
|
1198
|
+
Write-Host " Swarm Monitor: STOPPED" -ForegroundColor Red
|
|
1199
|
+
}
|
|
1200
|
+
Write-Host ""
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
switch ($Action) {
|
|
1204
|
+
'start' {
|
|
1205
|
+
Start-SwarmMonitor
|
|
1206
|
+
Show-Status
|
|
1207
|
+
}
|
|
1208
|
+
'stop' {
|
|
1209
|
+
Stop-SwarmMonitor
|
|
1210
|
+
Show-Status
|
|
1211
|
+
}
|
|
1212
|
+
'restart' {
|
|
1213
|
+
Stop-SwarmMonitor
|
|
1214
|
+
Start-Sleep -Seconds 1
|
|
1215
|
+
Start-SwarmMonitor
|
|
1216
|
+
Show-Status
|
|
1217
|
+
}
|
|
1218
|
+
'status' {
|
|
1219
|
+
Show-Status
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
`;
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Generate Windows batch file wrapper
|
|
1226
|
+
*/
|
|
1227
|
+
export function generateWindowsBatchWrapper() {
|
|
1228
|
+
return `@echo off
|
|
1229
|
+
REM RuFlo V3 - Windows Batch Wrapper
|
|
1230
|
+
REM Routes to PowerShell daemon manager
|
|
1231
|
+
|
|
1232
|
+
PowerShell -ExecutionPolicy Bypass -File "%~dp0daemon-manager.ps1" %*
|
|
1233
|
+
`;
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Generate cross-platform session manager
|
|
1237
|
+
*/
|
|
1238
|
+
export function generateCrossPlatformSessionManager() {
|
|
1239
|
+
return `#!/usr/bin/env node
|
|
1240
|
+
/**
|
|
1241
|
+
* Ruflo Cross-Platform Session Manager
|
|
1242
|
+
* Works on Windows, macOS, and Linux
|
|
1243
|
+
*/
|
|
1244
|
+
|
|
1245
|
+
const fs = require('fs');
|
|
1246
|
+
const path = require('path');
|
|
1247
|
+
const os = require('os');
|
|
1248
|
+
|
|
1249
|
+
// Platform-specific paths
|
|
1250
|
+
const platform = os.platform();
|
|
1251
|
+
const homeDir = os.homedir();
|
|
1252
|
+
|
|
1253
|
+
// Get data directory based on platform
|
|
1254
|
+
function getDataDir() {
|
|
1255
|
+
const localDir = path.join(process.cwd(), '.claude-flow', 'sessions');
|
|
1256
|
+
if (fs.existsSync(path.dirname(localDir))) {
|
|
1257
|
+
return localDir;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
switch (platform) {
|
|
1261
|
+
case 'win32':
|
|
1262
|
+
return path.join(process.env.APPDATA || homeDir, 'claude-flow', 'sessions');
|
|
1263
|
+
case 'darwin':
|
|
1264
|
+
return path.join(homeDir, 'Library', 'Application Support', 'claude-flow', 'sessions');
|
|
1265
|
+
default:
|
|
1266
|
+
return path.join(homeDir, '.claude-flow', 'sessions');
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
const SESSION_DIR = getDataDir();
|
|
1271
|
+
const SESSION_FILE = path.join(SESSION_DIR, 'current.json');
|
|
1272
|
+
|
|
1273
|
+
// Ensure directory exists
|
|
1274
|
+
function ensureDir(dir) {
|
|
1275
|
+
if (!fs.existsSync(dir)) {
|
|
1276
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
const commands = {
|
|
1281
|
+
start: () => {
|
|
1282
|
+
ensureDir(SESSION_DIR);
|
|
1283
|
+
const sessionId = \`session-\${Date.now()}\`;
|
|
1284
|
+
const session = {
|
|
1285
|
+
id: sessionId,
|
|
1286
|
+
startedAt: new Date().toISOString(),
|
|
1287
|
+
platform: platform,
|
|
1288
|
+
cwd: process.cwd(),
|
|
1289
|
+
context: {},
|
|
1290
|
+
metrics: { edits: 0, commands: 0, tasks: 0, errors: 0 }
|
|
1291
|
+
};
|
|
1292
|
+
fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
1293
|
+
console.log(\`Session started: \${sessionId}\`);
|
|
1294
|
+
return session;
|
|
1295
|
+
},
|
|
1296
|
+
|
|
1297
|
+
restore: () => {
|
|
1298
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
1299
|
+
console.log('No session to restore');
|
|
1300
|
+
return null;
|
|
1301
|
+
}
|
|
1302
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
1303
|
+
session.restoredAt = new Date().toISOString();
|
|
1304
|
+
fs.writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
|
|
1305
|
+
console.log(\`Session restored: \${session.id}\`);
|
|
1306
|
+
return session;
|
|
1307
|
+
},
|
|
1308
|
+
|
|
1309
|
+
end: () => {
|
|
1310
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
1311
|
+
console.log('No active session');
|
|
1312
|
+
return null;
|
|
1313
|
+
}
|
|
1314
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
1315
|
+
session.endedAt = new Date().toISOString();
|
|
1316
|
+
session.duration = Date.now() - new Date(session.startedAt).getTime();
|
|
1317
|
+
|
|
1318
|
+
const archivePath = path.join(SESSION_DIR, \`\${session.id}.json\`);
|
|
1319
|
+
fs.writeFileSync(archivePath, JSON.stringify(session, null, 2));
|
|
1320
|
+
fs.unlinkSync(SESSION_FILE);
|
|
1321
|
+
|
|
1322
|
+
console.log(\`Session ended: \${session.id}\`);
|
|
1323
|
+
console.log(\`Duration: \${Math.round(session.duration / 1000 / 60)} minutes\`);
|
|
1324
|
+
return session;
|
|
1325
|
+
},
|
|
1326
|
+
|
|
1327
|
+
status: () => {
|
|
1328
|
+
if (!fs.existsSync(SESSION_FILE)) {
|
|
1329
|
+
console.log('No active session');
|
|
1330
|
+
return null;
|
|
1331
|
+
}
|
|
1332
|
+
const session = JSON.parse(fs.readFileSync(SESSION_FILE, 'utf-8'));
|
|
1333
|
+
const duration = Date.now() - new Date(session.startedAt).getTime();
|
|
1334
|
+
console.log(\`Session: \${session.id}\`);
|
|
1335
|
+
console.log(\`Platform: \${session.platform}\`);
|
|
1336
|
+
console.log(\`Started: \${session.startedAt}\`);
|
|
1337
|
+
console.log(\`Duration: \${Math.round(duration / 1000 / 60)} minutes\`);
|
|
1338
|
+
return session;
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1342
|
+
// CLI
|
|
1343
|
+
const [,, command, ...args] = process.argv;
|
|
1344
|
+
if (command && commands[command]) {
|
|
1345
|
+
commands[command](...args);
|
|
1346
|
+
} else {
|
|
1347
|
+
console.log('Usage: session.js <start|restore|end|status>');
|
|
1348
|
+
console.log(\`Platform: \${platform}\`);
|
|
1349
|
+
console.log(\`Data dir: \${SESSION_DIR}\`);
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
module.exports = commands;
|
|
1353
|
+
`;
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
* Generate all helper files
|
|
1357
|
+
*/
|
|
1358
|
+
export function generateHelpers(options) {
|
|
1359
|
+
const helpers = {};
|
|
1360
|
+
if (options.components.helpers) {
|
|
1361
|
+
// Unix/macOS shell scripts
|
|
1362
|
+
helpers['pre-commit'] = generatePreCommitHook();
|
|
1363
|
+
helpers['post-commit'] = generatePostCommitHook();
|
|
1364
|
+
// Cross-platform Node.js scripts
|
|
1365
|
+
helpers['session.js'] = generateCrossPlatformSessionManager();
|
|
1366
|
+
helpers['router.js'] = generateAgentRouter();
|
|
1367
|
+
helpers['memory.js'] = generateMemoryHelper();
|
|
1368
|
+
// Windows-specific scripts
|
|
1369
|
+
helpers['daemon-manager.ps1'] = generateWindowsDaemonManager();
|
|
1370
|
+
helpers['daemon-manager.cmd'] = generateWindowsBatchWrapper();
|
|
1371
|
+
// ADR-127 Phase 4 — expose the attribution footer as a helper file only
|
|
1372
|
+
// when the user explicitly opts in. The file content is the single-line
|
|
1373
|
+
// string so init-generated PR templates can `cat .claude/helpers/attribution`
|
|
1374
|
+
// and append it conditionally without hard-wiring the string everywhere.
|
|
1375
|
+
if (options.attribution === true) {
|
|
1376
|
+
helpers['attribution'] = ATTRIBUTION_FOOTER + '\n';
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
if (options.components.statusline) {
|
|
1380
|
+
helpers['statusline.cjs'] = generateStatuslineScript(options); // .cjs for ES module compatibility
|
|
1381
|
+
helpers['statusline-hook.sh'] = generateStatuslineHook(options);
|
|
1382
|
+
}
|
|
1383
|
+
return helpers;
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Generate cross-platform Node.js port of ruflo-hook.sh (#2132).
|
|
1387
|
+
*
|
|
1388
|
+
* The bash shim works on Mac/Linux but fails on native Windows (exit 126).
|
|
1389
|
+
* This .cjs version is always deployed to .claude/helpers/ so:
|
|
1390
|
+
* - Windows: settings.json overrides plugin bash hooks with node-based cmds
|
|
1391
|
+
* - Mac/Linux: plugin hooks.json still uses .sh (faster, battle-tested)
|
|
1392
|
+
* - Both: .claude/helpers/ruflo-hook.cjs available as a canonical cross-platform shim
|
|
1393
|
+
*/
|
|
1394
|
+
export function generateRufloHookCjs() {
|
|
1395
|
+
return `#!/usr/bin/env node
|
|
1396
|
+
/**
|
|
1397
|
+
* ruflo-hook.cjs — cross-platform Node.js port of ruflo-hook.sh (#2132)
|
|
1398
|
+
*
|
|
1399
|
+
* Deployed to .claude/helpers/ during ruflo init. On Windows, the
|
|
1400
|
+
* generated .claude/settings.json hooks point here instead of the
|
|
1401
|
+
* plugin's bash-only ruflo-hook.sh.
|
|
1402
|
+
*
|
|
1403
|
+
* Always exits 0 — hook subcommands are best-effort telemetry and must
|
|
1404
|
+
* never block a Claude Code turn.
|
|
1405
|
+
*/
|
|
1406
|
+
|
|
1407
|
+
'use strict';
|
|
1408
|
+
|
|
1409
|
+
const { spawnSync, execSync } = require('child_process');
|
|
1410
|
+
const fs = require('fs');
|
|
1411
|
+
|
|
1412
|
+
function done() { process.exit(0); }
|
|
1413
|
+
|
|
1414
|
+
function commandExists(cmd) {
|
|
1415
|
+
try {
|
|
1416
|
+
const r = execSync(
|
|
1417
|
+
process.platform === 'win32' ? 'where ' + cmd : 'command -v ' + cmd,
|
|
1418
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }
|
|
1419
|
+
);
|
|
1420
|
+
return r.trim().length > 0;
|
|
1421
|
+
} catch { return false; }
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
function invokeHook(bin, binArgs, hookArgs, stdinData) {
|
|
1425
|
+
const args = [...binArgs, ...hookArgs];
|
|
1426
|
+
const result = spawnSync(bin, args, {
|
|
1427
|
+
shell: process.platform === 'win32',
|
|
1428
|
+
input: stdinData || '',
|
|
1429
|
+
encoding: 'utf8',
|
|
1430
|
+
stdio: ['pipe', 'ignore', 'ignore'],
|
|
1431
|
+
timeout: 30_000,
|
|
1432
|
+
});
|
|
1433
|
+
return result.status === 0;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
function main() {
|
|
1437
|
+
const args = process.argv.slice(2);
|
|
1438
|
+
if (args.length === 0) done();
|
|
1439
|
+
|
|
1440
|
+
const [subcommand, ...rest] = args;
|
|
1441
|
+
|
|
1442
|
+
let stdinData = '';
|
|
1443
|
+
try { stdinData = fs.readFileSync(0, 'utf8'); } catch { stdinData = ''; }
|
|
1444
|
+
|
|
1445
|
+
const hookArgs = ['hooks', subcommand, ...rest];
|
|
1446
|
+
|
|
1447
|
+
if (commandExists('ruflo')) { invokeHook('ruflo', [], hookArgs, stdinData); done(); }
|
|
1448
|
+
if (commandExists('claude-flow')) { invokeHook('claude-flow', [], hookArgs, stdinData); done(); }
|
|
1449
|
+
invokeHook('npx', ['--prefer-offline', '--yes', 'ruflo@latest'], hookArgs, stdinData);
|
|
1450
|
+
done();
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
main();
|
|
1454
|
+
`;
|
|
1455
|
+
}
|
|
1456
|
+
//# sourceMappingURL=helpers-generator.js.map
|