@claude-flow/cli 3.32.9 → 3.32.11
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/.proven-config-version +1 -0
- package/.claude/agents/analysis/analyze-code-quality.md +178 -178
- package/.claude/agents/analysis/code-analyzer.md +209 -209
- package/.claude/agents/analysis/code-review/analyze-code-quality.md +178 -178
- package/.claude/agents/architecture/arch-system-design.md +156 -156
- package/.claude/agents/architecture/system-design/arch-system-design.md +154 -154
- package/.claude/agents/browser/browser-agent.yaml +182 -182
- package/.claude/agents/consensus/byzantine-coordinator.md +62 -62
- package/.claude/agents/consensus/crdt-synchronizer.md +996 -996
- package/.claude/agents/consensus/gossip-coordinator.md +62 -62
- package/.claude/agents/consensus/performance-benchmarker.md +850 -850
- package/.claude/agents/consensus/quorum-manager.md +822 -822
- package/.claude/agents/consensus/raft-manager.md +62 -62
- package/.claude/agents/consensus/security-manager.md +621 -621
- package/.claude/agents/core/planner.md +374 -374
- package/.claude/agents/custom/test-long-runner.md +44 -44
- package/.claude/agents/data/data-ml-model.md +444 -444
- package/.claude/agents/data/ml/data-ml-model.md +192 -192
- package/.claude/agents/development/backend/dev-backend-api.md +141 -141
- package/.claude/agents/development/dev-backend-api.md +344 -344
- package/.claude/agents/devops/ci-cd/ops-cicd-github.md +163 -163
- package/.claude/agents/devops/ops-cicd-github.md +164 -164
- package/.claude/agents/documentation/api-docs/docs-api-openapi.md +173 -173
- package/.claude/agents/documentation/docs-api-openapi.md +354 -354
- package/.claude/agents/flow-nexus/app-store.md +87 -87
- package/.claude/agents/flow-nexus/authentication.md +68 -68
- package/.claude/agents/flow-nexus/challenges.md +80 -80
- package/.claude/agents/flow-nexus/neural-network.md +87 -87
- package/.claude/agents/flow-nexus/payments.md +82 -82
- package/.claude/agents/flow-nexus/sandbox.md +75 -75
- package/.claude/agents/flow-nexus/swarm.md +75 -75
- package/.claude/agents/flow-nexus/user-tools.md +95 -95
- package/.claude/agents/flow-nexus/workflow.md +83 -83
- package/.claude/agents/github/code-review-swarm.md +377 -377
- package/.claude/agents/github/github-modes.md +172 -172
- package/.claude/agents/github/issue-tracker.md +575 -575
- package/.claude/agents/github/multi-repo-swarm.md +552 -552
- package/.claude/agents/github/pr-manager.md +437 -437
- package/.claude/agents/github/project-board-sync.md +508 -508
- package/.claude/agents/github/release-manager.md +604 -604
- package/.claude/agents/github/release-swarm.md +582 -582
- package/.claude/agents/github/repo-architect.md +397 -397
- package/.claude/agents/github/swarm-issue.md +572 -572
- package/.claude/agents/github/swarm-pr.md +427 -427
- package/.claude/agents/github/sync-coordinator.md +451 -451
- package/.claude/agents/github/workflow-automation.md +902 -902
- package/.claude/agents/goal/agent.md +815 -815
- package/.claude/agents/optimization/benchmark-suite.md +664 -664
- package/.claude/agents/optimization/load-balancer.md +430 -430
- package/.claude/agents/optimization/performance-monitor.md +671 -671
- package/.claude/agents/optimization/resource-allocator.md +673 -673
- package/.claude/agents/optimization/topology-optimizer.md +807 -807
- package/.claude/agents/payments/agentic-payments.md +126 -126
- package/.claude/agents/sona/sona-learning-optimizer.md +74 -74
- package/.claude/agents/sparc/architecture.md +698 -698
- package/.claude/agents/sparc/pseudocode.md +519 -519
- package/.claude/agents/sparc/refinement.md +801 -801
- package/.claude/agents/sparc/specification.md +477 -477
- package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +224 -224
- package/.claude/agents/specialized/spec-mobile-react-native.md +226 -226
- package/.claude/agents/sublinear/consensus-coordinator.md +337 -337
- package/.claude/agents/sublinear/matrix-optimizer.md +184 -184
- package/.claude/agents/sublinear/pagerank-analyzer.md +298 -298
- package/.claude/agents/sublinear/performance-optimizer.md +367 -367
- package/.claude/agents/sublinear/trading-predictor.md +245 -245
- package/.claude/agents/swarm/adaptive-coordinator.md +1126 -1126
- package/.claude/agents/swarm/hierarchical-coordinator.md +709 -709
- package/.claude/agents/swarm/mesh-coordinator.md +962 -962
- package/.claude/agents/templates/automation-smart-agent.md +204 -204
- package/.claude/agents/templates/base-template-generator.md +289 -289
- package/.claude/agents/templates/coordinator-swarm-init.md +89 -89
- package/.claude/agents/templates/github-pr-manager.md +176 -176
- package/.claude/agents/templates/implementer-sparc-coder.md +258 -258
- package/.claude/agents/templates/memory-coordinator.md +186 -186
- package/.claude/agents/templates/orchestrator-task.md +138 -138
- package/.claude/agents/templates/performance-analyzer.md +198 -198
- package/.claude/agents/templates/sparc-coordinator.md +513 -513
- package/.claude/agents/testing/production-validator.md +394 -394
- package/.claude/agents/testing/tdd-london-swarm.md +243 -243
- package/.claude/agents/v3/aidefence-guardian.md +282 -282
- package/.claude/agents/v3/claims-authorizer.md +208 -208
- package/.claude/agents/v3/collective-intelligence-coordinator.md +993 -993
- package/.claude/agents/v3/ddd-domain-expert.md +220 -220
- package/.claude/agents/v3/injection-analyst.md +236 -236
- package/.claude/agents/v3/performance-engineer.md +1233 -1233
- package/.claude/agents/v3/pii-detector.md +151 -151
- package/.claude/agents/v3/reasoningbank-learner.md +213 -213
- package/.claude/agents/v3/security-architect-aidefence.md +410 -410
- package/.claude/agents/v3/security-architect.md +867 -867
- package/.claude/agents/v3/swarm-memory-manager.md +157 -157
- package/.claude/agents/v3/v3-integration-architect.md +205 -205
- package/.claude/commands/agents/README.md +50 -50
- package/.claude/commands/agents/agent-capabilities.md +140 -140
- package/.claude/commands/agents/agent-coordination.md +28 -28
- package/.claude/commands/agents/agent-spawning.md +28 -28
- package/.claude/commands/agents/agent-types.md +216 -216
- package/.claude/commands/agents/health.md +139 -139
- package/.claude/commands/agents/list.md +100 -100
- package/.claude/commands/agents/logs.md +130 -130
- package/.claude/commands/agents/metrics.md +122 -122
- package/.claude/commands/agents/pool.md +127 -127
- package/.claude/commands/agents/spawn.md +140 -140
- package/.claude/commands/agents/status.md +115 -115
- package/.claude/commands/agents/stop.md +102 -102
- package/.claude/commands/analysis/COMMAND_COMPLIANCE_REPORT.md +53 -53
- package/.claude/commands/analysis/README.md +9 -9
- package/.claude/commands/analysis/bottleneck-detect.md +162 -162
- package/.claude/commands/analysis/performance-bottlenecks.md +58 -58
- package/.claude/commands/analysis/performance-report.md +25 -25
- package/.claude/commands/analysis/token-efficiency.md +44 -44
- package/.claude/commands/analysis/token-usage.md +25 -25
- package/.claude/commands/automation/README.md +9 -9
- package/.claude/commands/automation/auto-agent.md +122 -122
- package/.claude/commands/automation/self-healing.md +105 -105
- package/.claude/commands/automation/session-memory.md +89 -89
- package/.claude/commands/automation/smart-agents.md +72 -72
- package/.claude/commands/automation/smart-spawn.md +25 -25
- package/.claude/commands/automation/workflow-select.md +25 -25
- package/.claude/commands/claude-flow-help.md +103 -103
- package/.claude/commands/claude-flow-memory.md +107 -107
- package/.claude/commands/claude-flow-swarm.md +205 -205
- package/.claude/commands/coordination/README.md +9 -9
- package/.claude/commands/coordination/agent-spawn.md +25 -25
- package/.claude/commands/coordination/init.md +44 -44
- package/.claude/commands/coordination/orchestrate.md +43 -43
- package/.claude/commands/coordination/spawn.md +45 -45
- package/.claude/commands/coordination/swarm-init.md +85 -85
- package/.claude/commands/coordination/task-orchestrate.md +25 -25
- package/.claude/commands/github/README.md +11 -11
- package/.claude/commands/github/code-review-swarm.md +513 -513
- package/.claude/commands/github/code-review.md +25 -25
- package/.claude/commands/github/github-modes.md +146 -146
- package/.claude/commands/github/github-swarm.md +121 -121
- package/.claude/commands/github/issue-tracker.md +291 -291
- package/.claude/commands/github/issue-triage.md +25 -25
- package/.claude/commands/github/multi-repo-swarm.md +518 -518
- package/.claude/commands/github/pr-enhance.md +26 -26
- package/.claude/commands/github/pr-manager.md +169 -169
- package/.claude/commands/github/project-board-sync.md +470 -470
- package/.claude/commands/github/release-manager.md +339 -339
- package/.claude/commands/github/release-swarm.md +543 -543
- package/.claude/commands/github/repo-analyze.md +25 -25
- package/.claude/commands/github/repo-architect.md +366 -366
- package/.claude/commands/github/swarm-issue.md +484 -484
- package/.claude/commands/github/swarm-pr.md +287 -287
- package/.claude/commands/github/sync-coordinator.md +302 -302
- package/.claude/commands/github/workflow-automation.md +441 -441
- package/.claude/commands/hive-mind/README.md +17 -17
- package/.claude/commands/hive-mind/hive-mind-consensus.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-init.md +18 -18
- package/.claude/commands/hive-mind/hive-mind-memory.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-metrics.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-resume.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-sessions.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-spawn.md +21 -21
- package/.claude/commands/hive-mind/hive-mind-status.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-stop.md +8 -8
- package/.claude/commands/hive-mind/hive-mind-wizard.md +8 -8
- package/.claude/commands/hive-mind/hive-mind.md +27 -27
- package/.claude/commands/hooks/README.md +11 -11
- package/.claude/commands/hooks/overview.md +57 -57
- package/.claude/commands/hooks/post-edit.md +117 -117
- package/.claude/commands/hooks/post-task.md +112 -112
- package/.claude/commands/hooks/pre-edit.md +113 -113
- package/.claude/commands/hooks/pre-task.md +111 -111
- package/.claude/commands/hooks/session-end.md +118 -118
- package/.claude/commands/hooks/setup.md +102 -102
- package/.claude/commands/memory/README.md +9 -9
- package/.claude/commands/memory/memory-persist.md +25 -25
- package/.claude/commands/memory/memory-search.md +25 -25
- package/.claude/commands/memory/memory-usage.md +25 -25
- package/.claude/commands/memory/neural.md +47 -47
- package/.claude/commands/monitoring/README.md +9 -9
- package/.claude/commands/monitoring/agent-metrics.md +25 -25
- package/.claude/commands/monitoring/agents.md +44 -44
- package/.claude/commands/monitoring/real-time-view.md +25 -25
- package/.claude/commands/monitoring/status.md +46 -46
- package/.claude/commands/monitoring/swarm-monitor.md +25 -25
- package/.claude/commands/optimization/README.md +9 -9
- package/.claude/commands/optimization/auto-topology.md +61 -61
- package/.claude/commands/optimization/cache-manage.md +25 -25
- package/.claude/commands/optimization/parallel-execute.md +25 -25
- package/.claude/commands/optimization/parallel-execution.md +49 -49
- package/.claude/commands/optimization/topology-optimize.md +25 -25
- package/.claude/commands/pair/README.md +260 -260
- package/.claude/commands/pair/commands.md +545 -545
- package/.claude/commands/pair/config.md +509 -509
- package/.claude/commands/pair/examples.md +511 -511
- package/.claude/commands/pair/modes.md +347 -347
- package/.claude/commands/pair/session.md +406 -406
- package/.claude/commands/pair/start.md +208 -208
- package/.claude/commands/sparc/analyzer.md +51 -51
- package/.claude/commands/sparc/architect.md +53 -53
- package/.claude/commands/sparc/ask.md +97 -97
- package/.claude/commands/sparc/batch-executor.md +54 -54
- package/.claude/commands/sparc/code.md +89 -89
- package/.claude/commands/sparc/coder.md +54 -54
- package/.claude/commands/sparc/debug.md +83 -83
- package/.claude/commands/sparc/debugger.md +54 -54
- package/.claude/commands/sparc/designer.md +53 -53
- package/.claude/commands/sparc/devops.md +109 -109
- package/.claude/commands/sparc/docs-writer.md +80 -80
- package/.claude/commands/sparc/documenter.md +54 -54
- package/.claude/commands/sparc/innovator.md +54 -54
- package/.claude/commands/sparc/integration.md +83 -83
- package/.claude/commands/sparc/mcp.md +117 -117
- package/.claude/commands/sparc/memory-manager.md +54 -54
- package/.claude/commands/sparc/optimizer.md +54 -54
- package/.claude/commands/sparc/orchestrator.md +131 -131
- package/.claude/commands/sparc/post-deployment-monitoring-mode.md +83 -83
- package/.claude/commands/sparc/refinement-optimization-mode.md +83 -83
- package/.claude/commands/sparc/researcher.md +54 -54
- package/.claude/commands/sparc/reviewer.md +54 -54
- package/.claude/commands/sparc/security-review.md +80 -80
- package/.claude/commands/sparc/sparc-modes.md +174 -174
- package/.claude/commands/sparc/sparc.md +111 -111
- package/.claude/commands/sparc/spec-pseudocode.md +80 -80
- package/.claude/commands/sparc/supabase-admin.md +348 -348
- package/.claude/commands/sparc/swarm-coordinator.md +54 -54
- package/.claude/commands/sparc/tdd.md +54 -54
- package/.claude/commands/sparc/tester.md +54 -54
- package/.claude/commands/sparc/tutorial.md +79 -79
- package/.claude/commands/sparc/workflow-manager.md +54 -54
- package/.claude/commands/sparc.md +166 -166
- package/.claude/commands/stream-chain/pipeline.md +120 -120
- package/.claude/commands/stream-chain/run.md +69 -69
- package/.claude/commands/swarm/README.md +15 -15
- package/.claude/commands/swarm/analysis.md +95 -95
- package/.claude/commands/swarm/development.md +96 -96
- package/.claude/commands/swarm/examples.md +168 -168
- package/.claude/commands/swarm/maintenance.md +102 -102
- package/.claude/commands/swarm/optimization.md +117 -117
- package/.claude/commands/swarm/research.md +136 -136
- package/.claude/commands/swarm/swarm-analysis.md +8 -8
- package/.claude/commands/swarm/swarm-background.md +8 -8
- package/.claude/commands/swarm/swarm-init.md +19 -19
- package/.claude/commands/swarm/swarm-modes.md +8 -8
- package/.claude/commands/swarm/swarm-monitor.md +8 -8
- package/.claude/commands/swarm/swarm-spawn.md +19 -19
- package/.claude/commands/swarm/swarm-status.md +8 -8
- package/.claude/commands/swarm/swarm-strategies.md +8 -8
- package/.claude/commands/swarm/swarm.md +87 -87
- package/.claude/commands/swarm/testing.md +131 -131
- package/.claude/commands/training/README.md +9 -9
- package/.claude/commands/training/model-update.md +25 -25
- package/.claude/commands/training/neural-patterns.md +107 -107
- package/.claude/commands/training/neural-train.md +75 -75
- package/.claude/commands/training/pattern-learn.md +25 -25
- package/.claude/commands/training/specialization.md +62 -62
- package/.claude/commands/truth/start.md +142 -142
- package/.claude/commands/verify/check.md +49 -49
- package/.claude/commands/verify/start.md +127 -127
- package/.claude/commands/workflows/README.md +9 -9
- package/.claude/commands/workflows/development.md +77 -77
- package/.claude/commands/workflows/research.md +62 -62
- package/.claude/commands/workflows/workflow-create.md +25 -25
- package/.claude/commands/workflows/workflow-execute.md +25 -25
- package/.claude/commands/workflows/workflow-export.md +25 -25
- package/.claude/eval/human-relevance-frozen-v1.json +17 -17
- package/.claude/evolve-proof/generation-0.json +211 -211
- package/.claude/evolve-proof/real-generation-0.json +406 -406
- package/.claude/evolve-proof/real-generation-1.json +406 -406
- package/.claude/helpers/.helpers-version +1 -1
- package/.claude/helpers/README.md +96 -96
- package/.claude/helpers/adr-compliance.sh +186 -186
- package/.claude/helpers/auto-commit.sh +178 -178
- package/.claude/helpers/auto-memory-hook.mjs +0 -0
- package/.claude/helpers/checkpoint-manager.sh +251 -251
- package/.claude/helpers/daemon-manager.sh +252 -252
- package/.claude/helpers/ddd-tracker.sh +144 -144
- package/.claude/helpers/github-safe.js +156 -156
- package/.claude/helpers/github-setup.sh +45 -45
- package/.claude/helpers/guidance-hook.sh +13 -13
- package/.claude/helpers/guidance-hooks.sh +102 -102
- package/.claude/helpers/health-monitor.sh +108 -108
- package/.claude/helpers/helpers.manifest.json +2 -2
- package/.claude/helpers/hook-handler.cjs +0 -0
- package/.claude/helpers/intelligence.cjs +0 -0
- package/.claude/helpers/learning-hooks.sh +329 -329
- package/.claude/helpers/learning-optimizer.sh +127 -127
- package/.claude/helpers/learning-service.mjs +1144 -1144
- package/.claude/helpers/memory.js +83 -83
- package/.claude/helpers/metrics-db.mjs +503 -503
- package/.claude/helpers/pattern-consolidator.sh +86 -86
- package/.claude/helpers/perf-worker.sh +160 -160
- package/.claude/helpers/post-commit +16 -16
- package/.claude/helpers/pre-commit +26 -26
- package/.claude/helpers/quick-start.sh +19 -19
- package/.claude/helpers/router.js +105 -105
- package/.claude/helpers/security-scanner.sh +127 -127
- package/.claude/helpers/session.js +157 -157
- package/.claude/helpers/setup-mcp.sh +18 -18
- package/.claude/helpers/standard-checkpoint-hooks.sh +189 -189
- package/.claude/helpers/statusline-hook.sh +21 -21
- package/.claude/helpers/statusline.cjs +0 -0
- package/.claude/helpers/statusline.js +340 -340
- package/.claude/helpers/swarm-comms.sh +353 -353
- package/.claude/helpers/swarm-hooks.sh +761 -761
- package/.claude/helpers/swarm-monitor.sh +210 -210
- package/.claude/helpers/sync-v3-metrics.sh +245 -245
- package/.claude/helpers/update-v3-progress.sh +165 -165
- package/.claude/helpers/v3-quick-status.sh +57 -57
- package/.claude/helpers/v3.sh +110 -110
- package/.claude/helpers/validate-v3-config.sh +215 -215
- package/.claude/helpers/worker-manager.sh +170 -170
- package/.claude/proven-config.json +42 -0
- package/.claude/proven-config.manifest.json +37 -37
- package/.claude/proven-config.signed.json +41 -41
- package/.claude/settings.json +182 -182
- package/.claude/skills/agentdb-advanced/SKILL.md +550 -550
- package/.claude/skills/agentdb-learning/SKILL.md +545 -545
- package/.claude/skills/agentdb-memory-patterns/SKILL.md +339 -339
- package/.claude/skills/agentdb-optimization/SKILL.md +509 -509
- package/.claude/skills/agentdb-vector-search/SKILL.md +339 -339
- package/.claude/skills/browser/SKILL.md +204 -204
- package/.claude/skills/dual-mode/README.md +71 -71
- package/.claude/skills/dual-mode/dual-collect.md +103 -103
- package/.claude/skills/dual-mode/dual-coordinate.md +85 -85
- package/.claude/skills/dual-mode/dual-spawn.md +81 -81
- package/.claude/skills/flow-nexus-neural/SKILL.md +727 -727
- package/.claude/skills/flow-nexus-platform/SKILL.md +1154 -1154
- package/.claude/skills/flow-nexus-swarm/SKILL.md +604 -604
- package/.claude/skills/github-code-review/SKILL.md +1125 -1125
- package/.claude/skills/github-multi-repo/SKILL.md +862 -862
- package/.claude/skills/github-project-management/SKILL.md +1262 -1262
- package/.claude/skills/github-release-management/SKILL.md +1064 -1064
- package/.claude/skills/github-workflow-automation/SKILL.md +1047 -1047
- package/.claude/skills/hooks-automation/SKILL.md +1201 -1201
- package/.claude/skills/pair-programming/SKILL.md +1202 -1202
- package/.claude/skills/reasoningbank-agentdb/SKILL.md +446 -446
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +201 -201
- package/.claude/skills/skill-builder/SKILL.md +910 -910
- package/.claude/skills/sparc-methodology/SKILL.md +1106 -1106
- package/.claude/skills/stream-chain/SKILL.md +560 -560
- package/.claude/skills/swarm-advanced/SKILL.md +970 -970
- package/.claude/skills/swarm-orchestration/SKILL.md +179 -179
- package/.claude/skills/v3-cli-modernization/SKILL.md +871 -871
- package/.claude/skills/v3-core-implementation/SKILL.md +796 -796
- package/.claude/skills/v3-ddd-architecture/SKILL.md +441 -441
- package/.claude/skills/v3-integration-deep/SKILL.md +240 -240
- package/.claude/skills/v3-mcp-optimization/SKILL.md +776 -776
- package/.claude/skills/v3-memory-unification/SKILL.md +173 -173
- package/.claude/skills/v3-performance-optimization/SKILL.md +389 -389
- package/.claude/skills/v3-security-overhaul/SKILL.md +81 -81
- package/.claude/skills/v3-swarm-coordination/SKILL.md +339 -339
- package/.claude/skills/verification-quality/SKILL.md +691 -691
- package/README.md +419 -419
- package/bin/cli.js +314 -314
- package/bin/mcp-server.js +224 -224
- package/bin/preinstall.cjs +2 -2
- package/catalog-manifest.json +2 -2
- package/dist/src/autopilot-state.js +24 -7
- package/dist/src/benchmarks/gaia-critic.js +24 -24
- package/dist/src/business-pods/bbs-budget-tracker.js +53 -53
- package/dist/src/commands/completions.js +409 -409
- package/dist/src/commands/daemon.js +44 -44
- package/dist/src/commands/embeddings.js +26 -26
- package/dist/src/commands/hive-mind.js +97 -97
- package/dist/src/commands/hooks.js +31 -10
- package/dist/src/commands/init.js +202 -34
- package/dist/src/commands/memory.js +12 -1
- package/dist/src/commands/ruvector/backup.js +23 -23
- package/dist/src/commands/ruvector/benchmark.js +31 -31
- package/dist/src/commands/ruvector/import.js +14 -14
- package/dist/src/commands/ruvector/init.js +115 -115
- package/dist/src/commands/ruvector/migrate.js +99 -99
- package/dist/src/commands/ruvector/optimize.js +51 -51
- package/dist/src/commands/ruvector/setup.js +624 -624
- package/dist/src/commands/ruvector/status.js +38 -38
- package/dist/src/config/proven-config.js +2 -2
- package/dist/src/funnel/disclosure.js +13 -2
- package/dist/src/funnel/messages.d.ts +12 -10
- package/dist/src/funnel/messages.js +83 -11
- package/dist/src/init/claudemd-generator.js +231 -231
- package/dist/src/init/executor.js +453 -453
- package/dist/src/init/helper-signing.js +2 -2
- package/dist/src/init/helpers-generator.js +751 -751
- package/dist/src/init/statusline-generator.js +24 -24
- package/dist/src/mcp-tools/agentdb-tools.js +15 -15
- package/dist/src/mcp-tools/browser-intent-tools.js +19 -19
- package/dist/src/mcp-tools/browser-tools.js +8 -0
- package/dist/src/mcp-tools/hooks-tools.js +21 -0
- package/dist/src/mcp-tools/memory-tools.js +4 -3
- package/dist/src/memory/graph-edge-writer.js +22 -22
- package/dist/src/memory/memory-bridge.js +248 -158
- package/dist/src/memory/memory-initializer.js +407 -407
- package/dist/src/memory/rabitq-index.js +5 -5
- package/dist/src/parser.js +25 -9
- package/dist/src/proxy/verify.js +2 -2
- package/dist/src/runtime/headless.js +28 -28
- package/dist/src/services/distill-tuning.js +7 -7
- package/dist/src/services/headless-worker-executor.js +84 -84
- package/dist/src/services/memory-distillation.js +4 -4
- package/dist/src/services/worker-daemon.js +7 -4
- package/dist/src/transfer/deploy-seraphine.js +23 -23
- package/package.json +137 -137
- package/plugins/ruflo-metaharness/.claude-plugin/plugin.json +32 -32
- package/plugins/ruflo-metaharness/README.md +72 -72
- package/plugins/ruflo-metaharness/agents/metaharness-architect.md +58 -58
- package/plugins/ruflo-metaharness/commands/ruflo-metaharness.md +48 -48
- package/plugins/ruflo-metaharness/scripts/_darwin.mjs +210 -210
- package/plugins/ruflo-metaharness/scripts/_harness.mjs +330 -330
- package/plugins/ruflo-metaharness/scripts/_invoke.mjs +231 -231
- package/plugins/ruflo-metaharness/scripts/_redblue.mjs +143 -143
- package/plugins/ruflo-metaharness/scripts/_similarity.mjs +161 -161
- package/plugins/ruflo-metaharness/scripts/_spike-similarity.mjs +223 -223
- package/plugins/ruflo-metaharness/scripts/audit-list.mjs +158 -158
- package/plugins/ruflo-metaharness/scripts/audit-trend.mjs +272 -272
- package/plugins/ruflo-metaharness/scripts/bench-parse-mcp-scan.mjs +146 -146
- package/plugins/ruflo-metaharness/scripts/bench-recordpair-overhead.mjs +186 -186
- package/plugins/ruflo-metaharness/scripts/bench-similarity.mjs +177 -177
- package/plugins/ruflo-metaharness/scripts/bench.mjs +95 -95
- package/plugins/ruflo-metaharness/scripts/drift-from-history.mjs +363 -363
- package/plugins/ruflo-metaharness/scripts/evolve.mjs +404 -404
- package/plugins/ruflo-metaharness/scripts/genome.mjs +80 -80
- package/plugins/ruflo-metaharness/scripts/gepa.mjs +153 -153
- package/plugins/ruflo-metaharness/scripts/learn.mjs +127 -127
- package/plugins/ruflo-metaharness/scripts/mcp-scan.mjs +111 -111
- package/plugins/ruflo-metaharness/scripts/mint.mjs +126 -126
- package/plugins/ruflo-metaharness/scripts/oia-audit.mjs +228 -228
- package/plugins/ruflo-metaharness/scripts/redblue.mjs +286 -286
- package/plugins/ruflo-metaharness/scripts/router-parallel-analyze.mjs +250 -250
- package/plugins/ruflo-metaharness/scripts/score.mjs +92 -92
- package/plugins/ruflo-metaharness/scripts/security-bench.mjs +174 -174
- package/plugins/ruflo-metaharness/scripts/similarity.mjs +158 -158
- package/plugins/ruflo-metaharness/scripts/smoke.sh +2356 -2356
- package/plugins/ruflo-metaharness/scripts/test-graceful-degradation.mjs +165 -165
- package/plugins/ruflo-metaharness/scripts/test-mcp-tools.mjs +472 -472
- package/plugins/ruflo-metaharness/scripts/test-parallel-pipeline.mjs +204 -204
- package/plugins/ruflo-metaharness/scripts/test-pipeline-roundtrip.mjs +586 -586
- package/plugins/ruflo-metaharness/scripts/test-similarity.mjs +334 -334
- package/plugins/ruflo-metaharness/scripts/test-with-openrouter.mjs +229 -229
- package/plugins/ruflo-metaharness/scripts/threat-model.mjs +59 -59
- package/plugins/ruflo-metaharness/skills/harness-bench/SKILL.md +64 -64
- package/plugins/ruflo-metaharness/skills/harness-drift-from-history/SKILL.md +65 -65
- package/plugins/ruflo-metaharness/skills/harness-evolve/SKILL.md +131 -131
- package/plugins/ruflo-metaharness/skills/harness-genome/SKILL.md +54 -54
- package/plugins/ruflo-metaharness/skills/harness-gepa/SKILL.md +65 -65
- package/plugins/ruflo-metaharness/skills/harness-learn/SKILL.md +65 -65
- package/plugins/ruflo-metaharness/skills/harness-mcp-scan/SKILL.md +49 -49
- package/plugins/ruflo-metaharness/skills/harness-mint/SKILL.md +72 -72
- package/plugins/ruflo-metaharness/skills/harness-oia-audit/SKILL.md +79 -79
- package/plugins/ruflo-metaharness/skills/harness-score/SKILL.md +66 -66
- package/plugins/ruflo-metaharness/skills/harness-security-bench/SKILL.md +101 -101
- package/plugins/ruflo-metaharness/skills/harness-similarity/SKILL.md +67 -67
- package/plugins/ruflo-metaharness/skills/harness-threat-model/SKILL.md +41 -41
- package/scripts/postinstall.cjs +153 -153
|
@@ -1,229 +1,229 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// test-with-openrouter.mjs — runtime test that exercises metaharness
|
|
3
|
-
// scaffolding + lifecycle commands using OPENROUTER_API_KEY fetched
|
|
4
|
-
// from GCP Secret Manager.
|
|
5
|
-
//
|
|
6
|
-
// WHAT IT DOES (end-to-end)
|
|
7
|
-
// 1. Fetch OPENROUTER_API_KEY from GCP Secret Manager via
|
|
8
|
-
// `gcloud secrets versions access latest --secret=OPENROUTER_API_KEY`
|
|
9
|
-
// 2. Verify the secret authenticates against OpenRouter by listing
|
|
10
|
-
// models (1 HTTP call, ~$0)
|
|
11
|
-
// 3. Scaffold a fresh harness into a temp dir via
|
|
12
|
-
// `metaharness new --name test-h --template vertical:coding
|
|
13
|
-
// --host claude-code --yes`
|
|
14
|
-
// 4. Run lifecycle commands against the scaffold:
|
|
15
|
-
// - harness doctor (smoke health check)
|
|
16
|
-
// - harness validate (full validation; --skip-gcp to avoid
|
|
17
|
-
// nested GCP fetches in this test)
|
|
18
|
-
// - harness score (5-dim scorecard of the scaffolded
|
|
19
|
-
// harness itself)
|
|
20
|
-
// - harness genome (7-section report)
|
|
21
|
-
// 5. (Optional) make one real LLM call through OpenRouter to a
|
|
22
|
-
// cheap model (e.g. openrouter/auto with a 1-token prompt) to
|
|
23
|
-
// prove the token works for actual inference
|
|
24
|
-
// 6. Clean up the temp dir
|
|
25
|
-
//
|
|
26
|
-
// COST: ~$0 (1 model-list call + optional <$0.0001 inference call)
|
|
27
|
-
//
|
|
28
|
-
// USAGE
|
|
29
|
-
// node scripts/test-with-openrouter.mjs # full e2e
|
|
30
|
-
// node scripts/test-with-openrouter.mjs --skip-inference # no LLM call
|
|
31
|
-
// node scripts/test-with-openrouter.mjs --keep-fixtures # leave scaffold for inspection
|
|
32
|
-
//
|
|
33
|
-
// EXIT CODES
|
|
34
|
-
// 0 all checks passed
|
|
35
|
-
// 1 at least one assertion failed
|
|
36
|
-
// 2 setup error (gcloud not authed, OPENROUTER_API_KEY missing in GCP, etc.)
|
|
37
|
-
// 3 cost/safety guard tripped
|
|
38
|
-
|
|
39
|
-
import { spawnSync, execSync } from 'node:child_process';
|
|
40
|
-
import { mkdtempSync, rmSync, mkdirSync, existsSync } from 'node:fs';
|
|
41
|
-
import { tmpdir } from 'node:os';
|
|
42
|
-
import { join } from 'node:path';
|
|
43
|
-
|
|
44
|
-
const ARGS = (() => {
|
|
45
|
-
const a = { skipInference: false, keep: false, format: 'table' };
|
|
46
|
-
for (let i = 2; i < process.argv.length; i++) {
|
|
47
|
-
const v = process.argv[i];
|
|
48
|
-
if (v === '--skip-inference') a.skipInference = true;
|
|
49
|
-
else if (v === '--keep-fixtures') a.keep = true;
|
|
50
|
-
else if (v === '--format') a.format = process.argv[++i];
|
|
51
|
-
}
|
|
52
|
-
return a;
|
|
53
|
-
})();
|
|
54
|
-
|
|
55
|
-
let passed = 0, failed = 0;
|
|
56
|
-
const failures = [];
|
|
57
|
-
function assert(cond, label) {
|
|
58
|
-
if (cond) { console.log(` ✓ ${label}`); passed++; }
|
|
59
|
-
else { console.log(` ✗ ${label}`); failures.push(label); failed++; }
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function fetchSecretFromGcp(secretName) {
|
|
63
|
-
try {
|
|
64
|
-
const out = execSync(
|
|
65
|
-
`gcloud secrets versions access latest --secret=${secretName}`,
|
|
66
|
-
{ encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 15_000 },
|
|
67
|
-
);
|
|
68
|
-
return out.trim();
|
|
69
|
-
} catch (e) {
|
|
70
|
-
console.error(` ⚠ gcloud secret fetch failed: ${(e.message || '').slice(0, 120)}`);
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function listOpenRouterModels(apiKey) {
|
|
76
|
-
const resp = await fetch('https://openrouter.ai/api/v1/models', {
|
|
77
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
78
|
-
});
|
|
79
|
-
if (!resp.ok) {
|
|
80
|
-
return { ok: false, status: resp.status, body: (await resp.text()).slice(0, 200) };
|
|
81
|
-
}
|
|
82
|
-
const data = await resp.json();
|
|
83
|
-
return { ok: true, modelCount: data.data?.length ?? 0 };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async function cheapInferenceCall(apiKey) {
|
|
87
|
-
// openrouter/auto picks the cheapest viable model; 5-token prompt;
|
|
88
|
-
// max_tokens=1 to bound cost at ~$0.00005.
|
|
89
|
-
const resp = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
|
90
|
-
method: 'POST',
|
|
91
|
-
headers: {
|
|
92
|
-
Authorization: `Bearer ${apiKey}`,
|
|
93
|
-
'Content-Type': 'application/json',
|
|
94
|
-
'HTTP-Referer': 'https://github.com/ruvnet/ruflo',
|
|
95
|
-
'X-Title': 'ruflo-metaharness-test',
|
|
96
|
-
},
|
|
97
|
-
body: JSON.stringify({
|
|
98
|
-
model: 'openrouter/auto',
|
|
99
|
-
messages: [{ role: 'user', content: 'OK' }],
|
|
100
|
-
max_tokens: 1,
|
|
101
|
-
}),
|
|
102
|
-
});
|
|
103
|
-
if (!resp.ok) return { ok: false, status: resp.status, body: (await resp.text()).slice(0, 200) };
|
|
104
|
-
const data = await resp.json();
|
|
105
|
-
return { ok: true, model: data.model, usage: data.usage };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function runHarness(args, opts = {}) {
|
|
109
|
-
const r = spawnSync('npx', ['-y', '-p', 'metaharness@latest', 'harness', ...args], {
|
|
110
|
-
stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf-8',
|
|
111
|
-
timeout: opts.timeoutMs ?? 60_000,
|
|
112
|
-
env: { ...process.env, ...opts.env },
|
|
113
|
-
});
|
|
114
|
-
return { exitCode: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' };
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function runMetaharness(args, opts = {}) {
|
|
118
|
-
const r = spawnSync('npx', ['-y', 'metaharness@latest', ...args], {
|
|
119
|
-
stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf-8',
|
|
120
|
-
timeout: opts.timeoutMs ?? 120_000,
|
|
121
|
-
cwd: opts.cwd, // metaharness new writes to cwd/<name>; --target is ignored
|
|
122
|
-
env: { ...process.env, ...opts.env },
|
|
123
|
-
});
|
|
124
|
-
return { exitCode: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async function main() {
|
|
128
|
-
console.log('# test-with-openrouter — metaharness × GCP × OpenRouter e2e\n');
|
|
129
|
-
|
|
130
|
-
// ── 0. Preflight ──────────────────────────────────────────────────
|
|
131
|
-
console.log('Phase 0 — preflight');
|
|
132
|
-
const gcloudWho = execSync('gcloud config get-value account 2>&1', { encoding: 'utf-8' }).trim();
|
|
133
|
-
assert(!!gcloudWho && !/None/.test(gcloudWho), `gcloud authenticated (${gcloudWho || 'none'})`);
|
|
134
|
-
|
|
135
|
-
// ── 1. Fetch OPENROUTER_API_KEY ───────────────────────────────────
|
|
136
|
-
console.log('\nPhase 1 — fetch OPENROUTER_API_KEY from GCP Secret Manager');
|
|
137
|
-
const apiKey = fetchSecretFromGcp('OPENROUTER_API_KEY');
|
|
138
|
-
assert(typeof apiKey === 'string' && apiKey.length > 20, 'OPENROUTER_API_KEY fetched (length OK)');
|
|
139
|
-
if (!apiKey) {
|
|
140
|
-
console.error('Setup error: cannot proceed without OPENROUTER_API_KEY. Skipping further phases.');
|
|
141
|
-
process.exit(2);
|
|
142
|
-
}
|
|
143
|
-
// Echo only length+prefix, never the raw key
|
|
144
|
-
console.log(` key length: ${apiKey.length}, prefix: ${apiKey.slice(0, 7)}…`);
|
|
145
|
-
|
|
146
|
-
// ── 2. Verify the key authenticates against OpenRouter ────────────
|
|
147
|
-
console.log('\nPhase 2 — verify OpenRouter authentication');
|
|
148
|
-
const modelsResp = await listOpenRouterModels(apiKey);
|
|
149
|
-
assert(modelsResp.ok, `OpenRouter /api/v1/models returns 2xx (got ${modelsResp.ok ? 'ok' : modelsResp.status})`);
|
|
150
|
-
if (modelsResp.ok) {
|
|
151
|
-
assert(modelsResp.modelCount > 10, `model list non-empty (${modelsResp.modelCount} models)`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// ── 3. Scaffold a fresh harness ───────────────────────────────────
|
|
155
|
-
// CRITICAL: `metaharness new <name>` writes to $CWD/<name> — the
|
|
156
|
-
// --target flag is ignored by the CLI (verified 2026-06-16 against
|
|
157
|
-
// metaharness@0.1.11). Run from inside a fresh temp dir so the
|
|
158
|
-
// scaffold lands there, not in the ruflo project root.
|
|
159
|
-
console.log('\nPhase 3 — scaffold a fresh harness');
|
|
160
|
-
const fixture = mkdtempSync(join(tmpdir(), 'ruflo-mh-openrouter-'));
|
|
161
|
-
const target = join(fixture, 'test-harness');
|
|
162
|
-
console.log(` fixture cwd: ${fixture}`);
|
|
163
|
-
console.log(` expected target: ${target}`);
|
|
164
|
-
const scaffold = runMetaharness(
|
|
165
|
-
['test-harness', '--template', 'vertical:coding', '--host', 'claude-code'],
|
|
166
|
-
{ timeoutMs: 180_000, cwd: fixture },
|
|
167
|
-
);
|
|
168
|
-
assert(scaffold.exitCode === 0, `metaharness new exit 0 (got ${scaffold.exitCode})`);
|
|
169
|
-
assert(existsSync(target), `target dir created at ${target}`);
|
|
170
|
-
|
|
171
|
-
// ── 4. Run lifecycle commands against the scaffold ────────────────
|
|
172
|
-
console.log('\nPhase 4 — lifecycle commands on the scaffold');
|
|
173
|
-
// harness doctor — quick smoke
|
|
174
|
-
const doc = runHarness(['doctor', target]);
|
|
175
|
-
assert(doc.exitCode === 0, `harness doctor exit 0 (got ${doc.exitCode})`);
|
|
176
|
-
|
|
177
|
-
// harness score on the scaffold itself
|
|
178
|
-
const score = runHarness(['score', target, '--json']);
|
|
179
|
-
assert(score.exitCode === 0, `harness score exit 0 (got ${score.exitCode})`);
|
|
180
|
-
const scoreJson = (() => {
|
|
181
|
-
const m = /\{[\s\S]*\}/.exec(score.stdout);
|
|
182
|
-
try { return m ? JSON.parse(m[0]) : null; } catch { return null; }
|
|
183
|
-
})();
|
|
184
|
-
assert(scoreJson && typeof scoreJson.score === 'number', 'score.json has numeric score');
|
|
185
|
-
|
|
186
|
-
// harness genome — exit 0 (ready) or 1 (needs-work) both acceptable.
|
|
187
|
-
// Only exit 2 (blocked / scan-error) is a real failure.
|
|
188
|
-
const gen = runHarness(['genome', target, '--json']);
|
|
189
|
-
assert(gen.exitCode === 0 || gen.exitCode === 1, `harness genome exit 0 or 1 (got ${gen.exitCode})`);
|
|
190
|
-
|
|
191
|
-
// harness mcp-scan
|
|
192
|
-
const scan = runHarness(['mcp-scan', target]);
|
|
193
|
-
// mcp-scan can exit 1 on findings; either 0 or 1 is acceptable here.
|
|
194
|
-
assert(scan.exitCode === 0 || scan.exitCode === 1, `harness mcp-scan exit 0 or 1 (got ${scan.exitCode})`);
|
|
195
|
-
|
|
196
|
-
// ── 5. (Optional) one real OpenRouter inference call ──────────────
|
|
197
|
-
if (!ARGS.skipInference) {
|
|
198
|
-
console.log('\nPhase 5 — single OpenRouter inference call (cheapest auto-route, max_tokens=1)');
|
|
199
|
-
const inf = await cheapInferenceCall(apiKey);
|
|
200
|
-
assert(inf.ok, `OpenRouter inference 2xx (got ${inf.ok ? 'ok' : inf.status})`);
|
|
201
|
-
if (inf.ok) {
|
|
202
|
-
console.log(` model used: ${inf.model}`);
|
|
203
|
-
console.log(` usage: prompt=${inf.usage?.prompt_tokens} completion=${inf.usage?.completion_tokens}`);
|
|
204
|
-
}
|
|
205
|
-
} else {
|
|
206
|
-
console.log('\nPhase 5 — SKIPPED (--skip-inference)');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// ── 6. Cleanup ────────────────────────────────────────────────────
|
|
210
|
-
if (!ARGS.keep) {
|
|
211
|
-
rmSync(fixture, { recursive: true, force: true });
|
|
212
|
-
console.log(`\nFixture cleaned: ${fixture}`);
|
|
213
|
-
} else {
|
|
214
|
-
console.log(`\nFixture kept at: ${fixture}`);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
console.log(`\n${passed} passed, ${failed} failed`);
|
|
218
|
-
if (failed > 0) {
|
|
219
|
-
console.log('\nFailures:');
|
|
220
|
-
for (const f of failures) console.log(` - ${f}`);
|
|
221
|
-
process.exit(1);
|
|
222
|
-
}
|
|
223
|
-
console.log('\n✓ All harness × OpenRouter integration checks passed.');
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
main().catch((e) => {
|
|
227
|
-
console.error('test-with-openrouter crashed:', e.message || e);
|
|
228
|
-
process.exit(2);
|
|
229
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// test-with-openrouter.mjs — runtime test that exercises metaharness
|
|
3
|
+
// scaffolding + lifecycle commands using OPENROUTER_API_KEY fetched
|
|
4
|
+
// from GCP Secret Manager.
|
|
5
|
+
//
|
|
6
|
+
// WHAT IT DOES (end-to-end)
|
|
7
|
+
// 1. Fetch OPENROUTER_API_KEY from GCP Secret Manager via
|
|
8
|
+
// `gcloud secrets versions access latest --secret=OPENROUTER_API_KEY`
|
|
9
|
+
// 2. Verify the secret authenticates against OpenRouter by listing
|
|
10
|
+
// models (1 HTTP call, ~$0)
|
|
11
|
+
// 3. Scaffold a fresh harness into a temp dir via
|
|
12
|
+
// `metaharness new --name test-h --template vertical:coding
|
|
13
|
+
// --host claude-code --yes`
|
|
14
|
+
// 4. Run lifecycle commands against the scaffold:
|
|
15
|
+
// - harness doctor (smoke health check)
|
|
16
|
+
// - harness validate (full validation; --skip-gcp to avoid
|
|
17
|
+
// nested GCP fetches in this test)
|
|
18
|
+
// - harness score (5-dim scorecard of the scaffolded
|
|
19
|
+
// harness itself)
|
|
20
|
+
// - harness genome (7-section report)
|
|
21
|
+
// 5. (Optional) make one real LLM call through OpenRouter to a
|
|
22
|
+
// cheap model (e.g. openrouter/auto with a 1-token prompt) to
|
|
23
|
+
// prove the token works for actual inference
|
|
24
|
+
// 6. Clean up the temp dir
|
|
25
|
+
//
|
|
26
|
+
// COST: ~$0 (1 model-list call + optional <$0.0001 inference call)
|
|
27
|
+
//
|
|
28
|
+
// USAGE
|
|
29
|
+
// node scripts/test-with-openrouter.mjs # full e2e
|
|
30
|
+
// node scripts/test-with-openrouter.mjs --skip-inference # no LLM call
|
|
31
|
+
// node scripts/test-with-openrouter.mjs --keep-fixtures # leave scaffold for inspection
|
|
32
|
+
//
|
|
33
|
+
// EXIT CODES
|
|
34
|
+
// 0 all checks passed
|
|
35
|
+
// 1 at least one assertion failed
|
|
36
|
+
// 2 setup error (gcloud not authed, OPENROUTER_API_KEY missing in GCP, etc.)
|
|
37
|
+
// 3 cost/safety guard tripped
|
|
38
|
+
|
|
39
|
+
import { spawnSync, execSync } from 'node:child_process';
|
|
40
|
+
import { mkdtempSync, rmSync, mkdirSync, existsSync } from 'node:fs';
|
|
41
|
+
import { tmpdir } from 'node:os';
|
|
42
|
+
import { join } from 'node:path';
|
|
43
|
+
|
|
44
|
+
const ARGS = (() => {
|
|
45
|
+
const a = { skipInference: false, keep: false, format: 'table' };
|
|
46
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
47
|
+
const v = process.argv[i];
|
|
48
|
+
if (v === '--skip-inference') a.skipInference = true;
|
|
49
|
+
else if (v === '--keep-fixtures') a.keep = true;
|
|
50
|
+
else if (v === '--format') a.format = process.argv[++i];
|
|
51
|
+
}
|
|
52
|
+
return a;
|
|
53
|
+
})();
|
|
54
|
+
|
|
55
|
+
let passed = 0, failed = 0;
|
|
56
|
+
const failures = [];
|
|
57
|
+
function assert(cond, label) {
|
|
58
|
+
if (cond) { console.log(` ✓ ${label}`); passed++; }
|
|
59
|
+
else { console.log(` ✗ ${label}`); failures.push(label); failed++; }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function fetchSecretFromGcp(secretName) {
|
|
63
|
+
try {
|
|
64
|
+
const out = execSync(
|
|
65
|
+
`gcloud secrets versions access latest --secret=${secretName}`,
|
|
66
|
+
{ encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 15_000 },
|
|
67
|
+
);
|
|
68
|
+
return out.trim();
|
|
69
|
+
} catch (e) {
|
|
70
|
+
console.error(` ⚠ gcloud secret fetch failed: ${(e.message || '').slice(0, 120)}`);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function listOpenRouterModels(apiKey) {
|
|
76
|
+
const resp = await fetch('https://openrouter.ai/api/v1/models', {
|
|
77
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
78
|
+
});
|
|
79
|
+
if (!resp.ok) {
|
|
80
|
+
return { ok: false, status: resp.status, body: (await resp.text()).slice(0, 200) };
|
|
81
|
+
}
|
|
82
|
+
const data = await resp.json();
|
|
83
|
+
return { ok: true, modelCount: data.data?.length ?? 0 };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function cheapInferenceCall(apiKey) {
|
|
87
|
+
// openrouter/auto picks the cheapest viable model; 5-token prompt;
|
|
88
|
+
// max_tokens=1 to bound cost at ~$0.00005.
|
|
89
|
+
const resp = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
headers: {
|
|
92
|
+
Authorization: `Bearer ${apiKey}`,
|
|
93
|
+
'Content-Type': 'application/json',
|
|
94
|
+
'HTTP-Referer': 'https://github.com/ruvnet/ruflo',
|
|
95
|
+
'X-Title': 'ruflo-metaharness-test',
|
|
96
|
+
},
|
|
97
|
+
body: JSON.stringify({
|
|
98
|
+
model: 'openrouter/auto',
|
|
99
|
+
messages: [{ role: 'user', content: 'OK' }],
|
|
100
|
+
max_tokens: 1,
|
|
101
|
+
}),
|
|
102
|
+
});
|
|
103
|
+
if (!resp.ok) return { ok: false, status: resp.status, body: (await resp.text()).slice(0, 200) };
|
|
104
|
+
const data = await resp.json();
|
|
105
|
+
return { ok: true, model: data.model, usage: data.usage };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function runHarness(args, opts = {}) {
|
|
109
|
+
const r = spawnSync('npx', ['-y', '-p', 'metaharness@latest', 'harness', ...args], {
|
|
110
|
+
stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf-8',
|
|
111
|
+
timeout: opts.timeoutMs ?? 60_000,
|
|
112
|
+
env: { ...process.env, ...opts.env },
|
|
113
|
+
});
|
|
114
|
+
return { exitCode: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function runMetaharness(args, opts = {}) {
|
|
118
|
+
const r = spawnSync('npx', ['-y', 'metaharness@latest', ...args], {
|
|
119
|
+
stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf-8',
|
|
120
|
+
timeout: opts.timeoutMs ?? 120_000,
|
|
121
|
+
cwd: opts.cwd, // metaharness new writes to cwd/<name>; --target is ignored
|
|
122
|
+
env: { ...process.env, ...opts.env },
|
|
123
|
+
});
|
|
124
|
+
return { exitCode: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function main() {
|
|
128
|
+
console.log('# test-with-openrouter — metaharness × GCP × OpenRouter e2e\n');
|
|
129
|
+
|
|
130
|
+
// ── 0. Preflight ──────────────────────────────────────────────────
|
|
131
|
+
console.log('Phase 0 — preflight');
|
|
132
|
+
const gcloudWho = execSync('gcloud config get-value account 2>&1', { encoding: 'utf-8' }).trim();
|
|
133
|
+
assert(!!gcloudWho && !/None/.test(gcloudWho), `gcloud authenticated (${gcloudWho || 'none'})`);
|
|
134
|
+
|
|
135
|
+
// ── 1. Fetch OPENROUTER_API_KEY ───────────────────────────────────
|
|
136
|
+
console.log('\nPhase 1 — fetch OPENROUTER_API_KEY from GCP Secret Manager');
|
|
137
|
+
const apiKey = fetchSecretFromGcp('OPENROUTER_API_KEY');
|
|
138
|
+
assert(typeof apiKey === 'string' && apiKey.length > 20, 'OPENROUTER_API_KEY fetched (length OK)');
|
|
139
|
+
if (!apiKey) {
|
|
140
|
+
console.error('Setup error: cannot proceed without OPENROUTER_API_KEY. Skipping further phases.');
|
|
141
|
+
process.exit(2);
|
|
142
|
+
}
|
|
143
|
+
// Echo only length+prefix, never the raw key
|
|
144
|
+
console.log(` key length: ${apiKey.length}, prefix: ${apiKey.slice(0, 7)}…`);
|
|
145
|
+
|
|
146
|
+
// ── 2. Verify the key authenticates against OpenRouter ────────────
|
|
147
|
+
console.log('\nPhase 2 — verify OpenRouter authentication');
|
|
148
|
+
const modelsResp = await listOpenRouterModels(apiKey);
|
|
149
|
+
assert(modelsResp.ok, `OpenRouter /api/v1/models returns 2xx (got ${modelsResp.ok ? 'ok' : modelsResp.status})`);
|
|
150
|
+
if (modelsResp.ok) {
|
|
151
|
+
assert(modelsResp.modelCount > 10, `model list non-empty (${modelsResp.modelCount} models)`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ── 3. Scaffold a fresh harness ───────────────────────────────────
|
|
155
|
+
// CRITICAL: `metaharness new <name>` writes to $CWD/<name> — the
|
|
156
|
+
// --target flag is ignored by the CLI (verified 2026-06-16 against
|
|
157
|
+
// metaharness@0.1.11). Run from inside a fresh temp dir so the
|
|
158
|
+
// scaffold lands there, not in the ruflo project root.
|
|
159
|
+
console.log('\nPhase 3 — scaffold a fresh harness');
|
|
160
|
+
const fixture = mkdtempSync(join(tmpdir(), 'ruflo-mh-openrouter-'));
|
|
161
|
+
const target = join(fixture, 'test-harness');
|
|
162
|
+
console.log(` fixture cwd: ${fixture}`);
|
|
163
|
+
console.log(` expected target: ${target}`);
|
|
164
|
+
const scaffold = runMetaharness(
|
|
165
|
+
['test-harness', '--template', 'vertical:coding', '--host', 'claude-code'],
|
|
166
|
+
{ timeoutMs: 180_000, cwd: fixture },
|
|
167
|
+
);
|
|
168
|
+
assert(scaffold.exitCode === 0, `metaharness new exit 0 (got ${scaffold.exitCode})`);
|
|
169
|
+
assert(existsSync(target), `target dir created at ${target}`);
|
|
170
|
+
|
|
171
|
+
// ── 4. Run lifecycle commands against the scaffold ────────────────
|
|
172
|
+
console.log('\nPhase 4 — lifecycle commands on the scaffold');
|
|
173
|
+
// harness doctor — quick smoke
|
|
174
|
+
const doc = runHarness(['doctor', target]);
|
|
175
|
+
assert(doc.exitCode === 0, `harness doctor exit 0 (got ${doc.exitCode})`);
|
|
176
|
+
|
|
177
|
+
// harness score on the scaffold itself
|
|
178
|
+
const score = runHarness(['score', target, '--json']);
|
|
179
|
+
assert(score.exitCode === 0, `harness score exit 0 (got ${score.exitCode})`);
|
|
180
|
+
const scoreJson = (() => {
|
|
181
|
+
const m = /\{[\s\S]*\}/.exec(score.stdout);
|
|
182
|
+
try { return m ? JSON.parse(m[0]) : null; } catch { return null; }
|
|
183
|
+
})();
|
|
184
|
+
assert(scoreJson && typeof scoreJson.score === 'number', 'score.json has numeric score');
|
|
185
|
+
|
|
186
|
+
// harness genome — exit 0 (ready) or 1 (needs-work) both acceptable.
|
|
187
|
+
// Only exit 2 (blocked / scan-error) is a real failure.
|
|
188
|
+
const gen = runHarness(['genome', target, '--json']);
|
|
189
|
+
assert(gen.exitCode === 0 || gen.exitCode === 1, `harness genome exit 0 or 1 (got ${gen.exitCode})`);
|
|
190
|
+
|
|
191
|
+
// harness mcp-scan
|
|
192
|
+
const scan = runHarness(['mcp-scan', target]);
|
|
193
|
+
// mcp-scan can exit 1 on findings; either 0 or 1 is acceptable here.
|
|
194
|
+
assert(scan.exitCode === 0 || scan.exitCode === 1, `harness mcp-scan exit 0 or 1 (got ${scan.exitCode})`);
|
|
195
|
+
|
|
196
|
+
// ── 5. (Optional) one real OpenRouter inference call ──────────────
|
|
197
|
+
if (!ARGS.skipInference) {
|
|
198
|
+
console.log('\nPhase 5 — single OpenRouter inference call (cheapest auto-route, max_tokens=1)');
|
|
199
|
+
const inf = await cheapInferenceCall(apiKey);
|
|
200
|
+
assert(inf.ok, `OpenRouter inference 2xx (got ${inf.ok ? 'ok' : inf.status})`);
|
|
201
|
+
if (inf.ok) {
|
|
202
|
+
console.log(` model used: ${inf.model}`);
|
|
203
|
+
console.log(` usage: prompt=${inf.usage?.prompt_tokens} completion=${inf.usage?.completion_tokens}`);
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
console.log('\nPhase 5 — SKIPPED (--skip-inference)');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ── 6. Cleanup ────────────────────────────────────────────────────
|
|
210
|
+
if (!ARGS.keep) {
|
|
211
|
+
rmSync(fixture, { recursive: true, force: true });
|
|
212
|
+
console.log(`\nFixture cleaned: ${fixture}`);
|
|
213
|
+
} else {
|
|
214
|
+
console.log(`\nFixture kept at: ${fixture}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
console.log(`\n${passed} passed, ${failed} failed`);
|
|
218
|
+
if (failed > 0) {
|
|
219
|
+
console.log('\nFailures:');
|
|
220
|
+
for (const f of failures) console.log(` - ${f}`);
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
|
223
|
+
console.log('\n✓ All harness × OpenRouter integration checks passed.');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
main().catch((e) => {
|
|
227
|
+
console.error('test-with-openrouter crashed:', e.message || e);
|
|
228
|
+
process.exit(2);
|
|
229
|
+
});
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// threat-model.mjs — wrapper around `harness threat-model <path>`.
|
|
3
|
-
//
|
|
4
|
-
// USAGE
|
|
5
|
-
// node scripts/threat-model.mjs --path . --fail-on high --format json
|
|
6
|
-
|
|
7
|
-
import { runHarness, emitDegradedJsonAndExit } from './_harness.mjs';
|
|
8
|
-
|
|
9
|
-
const SEVERITY_RANK = { clean: 0, low: 1, medium: 2, high: 3 };
|
|
10
|
-
|
|
11
|
-
const ARGS = (() => {
|
|
12
|
-
const a = { path: '.', format: 'json', failOn: 'high' };
|
|
13
|
-
for (let i = 2; i < process.argv.length; i++) {
|
|
14
|
-
const v = process.argv[i];
|
|
15
|
-
if (v === '--path') a.path = process.argv[++i];
|
|
16
|
-
else if (v === '--fail-on') a.failOn = String(process.argv[++i] || 'high').toLowerCase();
|
|
17
|
-
else if (v === '--format') a.format = process.argv[++i];
|
|
18
|
-
}
|
|
19
|
-
return a;
|
|
20
|
-
})();
|
|
21
|
-
|
|
22
|
-
function main() {
|
|
23
|
-
if (!SEVERITY_RANK.hasOwnProperty(ARGS.failOn)) {
|
|
24
|
-
console.error(`threat-model: --fail-on must be one of clean|low|medium|high`);
|
|
25
|
-
process.exit(2);
|
|
26
|
-
}
|
|
27
|
-
const r = runHarness(['threat-model', ARGS.path]);
|
|
28
|
-
if (r.degraded) { emitDegradedJsonAndExit(r.reason); return; }
|
|
29
|
-
if (r.exitCode !== 0 && r.exitCode !== 1) {
|
|
30
|
-
console.error(`threat-model: harness exited ${r.exitCode}`);
|
|
31
|
-
if (r.stderr) console.error(r.stderr.slice(0, 400));
|
|
32
|
-
process.exit(2);
|
|
33
|
-
}
|
|
34
|
-
const payload = r.json ?? { rawStdout: r.stdout.slice(0, 400) };
|
|
35
|
-
const worst = String(payload?.worst || 'clean').toLowerCase();
|
|
36
|
-
const threshold = SEVERITY_RANK[ARGS.failOn];
|
|
37
|
-
const triggered = SEVERITY_RANK[worst] >= threshold && threshold > 0;
|
|
38
|
-
const alert = {
|
|
39
|
-
threshold: ARGS.failOn, worst, triggered,
|
|
40
|
-
reason: triggered
|
|
41
|
-
? `worst=${worst} at or above ${ARGS.failOn}`
|
|
42
|
-
: `worst=${worst} below ${ARGS.failOn} — OK`,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
if (ARGS.format === 'json') {
|
|
46
|
-
console.log(JSON.stringify({ ...payload, durationMs: r.durationMs, alert }, null, 2));
|
|
47
|
-
} else {
|
|
48
|
-
console.log(`# harness threat-model — ${ARGS.path}`);
|
|
49
|
-
console.log('');
|
|
50
|
-
console.log(`Worst severity: ${worst}`);
|
|
51
|
-
console.log(`Findings: ${(payload?.findings || []).length}`);
|
|
52
|
-
console.log('');
|
|
53
|
-
console.log(alert.triggered ? `⚠ **ALERT**: ${alert.reason}` : `✓ ${alert.reason}`);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (alert.triggered) process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// threat-model.mjs — wrapper around `harness threat-model <path>`.
|
|
3
|
+
//
|
|
4
|
+
// USAGE
|
|
5
|
+
// node scripts/threat-model.mjs --path . --fail-on high --format json
|
|
6
|
+
|
|
7
|
+
import { runHarness, emitDegradedJsonAndExit } from './_harness.mjs';
|
|
8
|
+
|
|
9
|
+
const SEVERITY_RANK = { clean: 0, low: 1, medium: 2, high: 3 };
|
|
10
|
+
|
|
11
|
+
const ARGS = (() => {
|
|
12
|
+
const a = { path: '.', format: 'json', failOn: 'high' };
|
|
13
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
14
|
+
const v = process.argv[i];
|
|
15
|
+
if (v === '--path') a.path = process.argv[++i];
|
|
16
|
+
else if (v === '--fail-on') a.failOn = String(process.argv[++i] || 'high').toLowerCase();
|
|
17
|
+
else if (v === '--format') a.format = process.argv[++i];
|
|
18
|
+
}
|
|
19
|
+
return a;
|
|
20
|
+
})();
|
|
21
|
+
|
|
22
|
+
function main() {
|
|
23
|
+
if (!SEVERITY_RANK.hasOwnProperty(ARGS.failOn)) {
|
|
24
|
+
console.error(`threat-model: --fail-on must be one of clean|low|medium|high`);
|
|
25
|
+
process.exit(2);
|
|
26
|
+
}
|
|
27
|
+
const r = runHarness(['threat-model', ARGS.path]);
|
|
28
|
+
if (r.degraded) { emitDegradedJsonAndExit(r.reason); return; }
|
|
29
|
+
if (r.exitCode !== 0 && r.exitCode !== 1) {
|
|
30
|
+
console.error(`threat-model: harness exited ${r.exitCode}`);
|
|
31
|
+
if (r.stderr) console.error(r.stderr.slice(0, 400));
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
const payload = r.json ?? { rawStdout: r.stdout.slice(0, 400) };
|
|
35
|
+
const worst = String(payload?.worst || 'clean').toLowerCase();
|
|
36
|
+
const threshold = SEVERITY_RANK[ARGS.failOn];
|
|
37
|
+
const triggered = SEVERITY_RANK[worst] >= threshold && threshold > 0;
|
|
38
|
+
const alert = {
|
|
39
|
+
threshold: ARGS.failOn, worst, triggered,
|
|
40
|
+
reason: triggered
|
|
41
|
+
? `worst=${worst} at or above ${ARGS.failOn}`
|
|
42
|
+
: `worst=${worst} below ${ARGS.failOn} — OK`,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
if (ARGS.format === 'json') {
|
|
46
|
+
console.log(JSON.stringify({ ...payload, durationMs: r.durationMs, alert }, null, 2));
|
|
47
|
+
} else {
|
|
48
|
+
console.log(`# harness threat-model — ${ARGS.path}`);
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log(`Worst severity: ${worst}`);
|
|
51
|
+
console.log(`Findings: ${(payload?.findings || []).length}`);
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log(alert.triggered ? `⚠ **ALERT**: ${alert.reason}` : `✓ ${alert.reason}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (alert.triggered) process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main();
|