claude-flow 3.14.4 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,8 @@
4
4
  "Bash(mkdir -p /tmp/ruflo-smoke)",
5
5
  "Bash(rm -rf /tmp/ruflo-smoke/*)",
6
6
  "Read(//tmp/**)",
7
- "Bash(npm pack *)"
7
+ "Bash(npm pack *)",
8
+ "WebFetch(domain:www.npmjs.com)"
8
9
  ]
9
10
  }
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.14.4",
3
+ "version": "3.15.0",
4
4
  "description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -56,6 +56,9 @@ const SUBCOMMANDS = {
56
56
  // iter 53 — one-command drift detection (compose audit-list + oia-audit + audit-trend)
57
57
  'drift-from-history': 'drift-from-history.mjs',
58
58
  mint: 'mint.mjs',
59
+ // @metaharness/redblue@~0.1.1 — adversarial red/blue LLM testing
60
+ // (init|run|patch|attack|report sub-subcommands handled by redblue.mjs)
61
+ redblue: 'redblue.mjs',
59
62
  };
60
63
  /**
61
64
  * Walk up from the current dirname to find the ruflo repo root that
@@ -63,8 +66,16 @@ const SUBCOMMANDS = {
63
66
  * 1. ruflo dev tree (cwd / ../plugins/...)
64
67
  * 2. ruflo wrapper (ruflo/node_modules/@claude-flow/cli/...)
65
68
  * 3. npx (npm-cache/__npx/... — fall back to cwd-scan)
69
+ *
70
+ * `requiredScript`, if provided, narrows the match: the returned dir must
71
+ * contain BOTH `_harness.mjs` (proves it's a plugin-scripts dir) AND the
72
+ * named script. This guards against the publish-artifact mirror at
73
+ * `v3/@claude-flow/cli/plugins/ruflo-metaharness/scripts/` getting picked
74
+ * over the source `plugins/ruflo-metaharness/scripts/` when the mirror
75
+ * lags the source (the mirror is regenerated only at publish time by
76
+ * `prepublishOnly`).
66
77
  */
67
- function locatePluginScripts() {
78
+ function locatePluginScripts(requiredScript) {
68
79
  const candidates = [];
69
80
  // Up from the cli dist dir
70
81
  let p = resolve(__dirname);
@@ -80,8 +91,11 @@ function locatePluginScripts() {
80
91
  candidates.push(join(cwd, 'plugins', 'ruflo-metaharness', 'scripts'));
81
92
  candidates.push(join(cwd, 'node_modules', '@claude-flow', 'cli', 'plugins', 'ruflo-metaharness', 'scripts'));
82
93
  for (const c of candidates) {
83
- if (existsSync(join(c, '_harness.mjs')))
84
- return c;
94
+ if (!existsSync(join(c, '_harness.mjs')))
95
+ continue;
96
+ if (requiredScript && !existsSync(join(c, requiredScript)))
97
+ continue;
98
+ return c;
85
99
  }
86
100
  return null;
87
101
  }
@@ -107,7 +121,7 @@ export const metaharnessCommand = {
107
121
  // iter 73 — list reflects all 10 dispatchable subcommands (was
108
122
  // stale at the iter-3 list of 5). Keep this synced with the
109
123
  // SUBCOMMANDS map above.
110
- description: 'One of: score | genome | mcp-scan | threat-model | oia-audit | audit-list | audit-trend | similarity | drift-from-history | mint',
124
+ description: 'One of: score | genome | mcp-scan | threat-model | oia-audit | audit-list | audit-trend | similarity | drift-from-history | mint | redblue',
111
125
  type: 'string',
112
126
  },
113
127
  ],
@@ -169,6 +183,7 @@ export const metaharnessCommand = {
169
183
  output.writeln(' similarity ADR-152 — weighted similarity between two harness fingerprints');
170
184
  output.writeln(' drift-from-history iter 53 — diff current state against most recent audit (1-command drift)');
171
185
  output.writeln(' mint scaffold a custom harness (dry-run by default)');
186
+ output.writeln(' redblue adversarial red/blue LLM testing (init|run|patch|attack|report)');
172
187
  output.writeln('');
173
188
  output.writeln('Each subcommand accepts --format json|table and --help.');
174
189
  output.writeln('');
@@ -180,7 +195,7 @@ export const metaharnessCommand = {
180
195
  output.writeln(`Valid: ${Object.keys(SUBCOMMANDS).join(', ')}`);
181
196
  return { success: false, exitCode: 2, data: { subcommand } };
182
197
  }
183
- const scriptDir = locatePluginScripts();
198
+ const scriptDir = locatePluginScripts(SUBCOMMANDS[subcommand]);
184
199
  if (!scriptDir) {
185
200
  output.writeln(output.warning('metaharness: plugins/ruflo-metaharness/scripts/ not found. Install ruflo with `npm i ruflo` or run from the ruflo repo.'));
186
201
  output.writeln(output.dim('(ADR-150 graceful degradation: this command is a thin delegator over the plugin; the plugin must be present.)'));
@@ -47,6 +47,9 @@ import { guidanceTools } from './mcp-tools/guidance-tools.js';
47
47
  import { autopilotTools } from './mcp-tools/autopilot-tools.js';
48
48
  // ADR-150 — MetaHarness MCP tools (score / genome / mcp-scan / threat-model / oia-audit)
49
49
  import { metaharnessTools } from './mcp-tools/metaharness-tools.js';
50
+ // agenticow@~0.2.3 — Copy-On-Write memory branching tools (162-byte branches);
51
+ // optional runtime dep, every handler returns `{degraded: true}` when missing.
52
+ import { agenticowTools } from './mcp-tools/agenticow-tools.js';
50
53
  // #1916: coverage-aware routing tools — defined in ruvector/coverage-tools.ts
51
54
  // but were never registered, so the `ruflo hooks coverage-*` CLI subcommands
52
55
  // failed with `Tool not found: hooks_coverage-route`.
@@ -127,6 +130,8 @@ registerTools([
127
130
  ...coverageRouterTools,
128
131
  // ADR-150 — MetaHarness static-analysis tools (5)
129
132
  ...metaharnessTools,
133
+ // agenticow@~0.2.3 — COW memory branching (4 tools, graceful-degraded when missing)
134
+ ...agenticowTools,
130
135
  ]);
131
136
  /**
132
137
  * MCP Client Error
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Agenticow MCP Tools — Copy-On-Write memory branching surface.
3
+ *
4
+ * Exposes `agenticow@~0.2.3` (a sibling RVF-based COW vector store by the same
5
+ * author as ruflo) as MCP tools so agents can branch, checkpoint, rollback,
6
+ * and promote memory state without copying GB-scale `.rvf` files.
7
+ *
8
+ * Motivation:
9
+ * The v3.14.4 release uncovered a tarball-bloat regression where Darwin
10
+ * loops' git-worktree-per-agent pattern accumulated 3.3 GB of disk. The
11
+ * structural cause was full-copy snapshot semantics. Measured agenticow
12
+ * branches are exactly 162 bytes regardless of base size (see
13
+ * `docs/agenticow/findings.md` for the bench data).
14
+ *
15
+ * Architectural constraint (mirrors metaharness-tools.ts / testgen-tools.ts):
16
+ * - `agenticow` lives in `optionalDependencies` — must NOT be a hard runtime dep
17
+ * - When the package is missing, every tool returns
18
+ * `{success: true, degraded: true, reason: 'agenticow-not-found'}`
19
+ * so callers see one contract regardless of install state
20
+ *
21
+ * Measured performance vs published claims (agenticow@0.2.3):
22
+ * ✅ 162-byte branches — confirmed exact
23
+ * ✅ 3,000×–180,000× smaller than full-copy at N=1k–50k
24
+ * ❌ 0.5 ms branch — measured ~10ms (fixed cost, not size-proportional)
25
+ * ❌ 83× faster — only beats full-copy past N ≈ 30k crossover
26
+ *
27
+ * Use cases (per ADR / findings doc):
28
+ * - Per-Darwin-iteration memory branching (eliminates worktree bloat)
29
+ * - Per-user / per-session personalization (cheap fork, no full copy)
30
+ * - Federation: branch → promote back as merge semantics
31
+ *
32
+ * @module @claude-flow/cli/mcp-tools/agenticow
33
+ */
34
+ import type { MCPTool } from './types.js';
35
+ export declare const agenticowTools: MCPTool[];
36
+ //# sourceMappingURL=agenticow-tools.d.ts.map
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Agenticow MCP Tools — Copy-On-Write memory branching surface.
3
+ *
4
+ * Exposes `agenticow@~0.2.3` (a sibling RVF-based COW vector store by the same
5
+ * author as ruflo) as MCP tools so agents can branch, checkpoint, rollback,
6
+ * and promote memory state without copying GB-scale `.rvf` files.
7
+ *
8
+ * Motivation:
9
+ * The v3.14.4 release uncovered a tarball-bloat regression where Darwin
10
+ * loops' git-worktree-per-agent pattern accumulated 3.3 GB of disk. The
11
+ * structural cause was full-copy snapshot semantics. Measured agenticow
12
+ * branches are exactly 162 bytes regardless of base size (see
13
+ * `docs/agenticow/findings.md` for the bench data).
14
+ *
15
+ * Architectural constraint (mirrors metaharness-tools.ts / testgen-tools.ts):
16
+ * - `agenticow` lives in `optionalDependencies` — must NOT be a hard runtime dep
17
+ * - When the package is missing, every tool returns
18
+ * `{success: true, degraded: true, reason: 'agenticow-not-found'}`
19
+ * so callers see one contract regardless of install state
20
+ *
21
+ * Measured performance vs published claims (agenticow@0.2.3):
22
+ * ✅ 162-byte branches — confirmed exact
23
+ * ✅ 3,000×–180,000× smaller than full-copy at N=1k–50k
24
+ * ❌ 0.5 ms branch — measured ~10ms (fixed cost, not size-proportional)
25
+ * ❌ 83× faster — only beats full-copy past N ≈ 30k crossover
26
+ *
27
+ * Use cases (per ADR / findings doc):
28
+ * - Per-Darwin-iteration memory branching (eliminates worktree bloat)
29
+ * - Per-user / per-session personalization (cheap fork, no full copy)
30
+ * - Federation: branch → promote back as merge semantics
31
+ *
32
+ * @module @claude-flow/cli/mcp-tools/agenticow
33
+ */
34
+ import { existsSync } from 'node:fs';
35
+ import { getProjectCwd } from './types.js';
36
+ import { resolve, isAbsolute } from 'node:path';
37
+ const PACKAGE_NAME = 'agenticow';
38
+ // Cache: module load is expensive enough to amortize across handler calls.
39
+ // null = not yet attempted; false = attempted and unavailable; module = loaded.
40
+ let _agenticowMod = null;
41
+ let _loadAttempted = false;
42
+ async function loadAgenticow() {
43
+ if (_loadAttempted)
44
+ return _agenticowMod;
45
+ _loadAttempted = true;
46
+ try {
47
+ _agenticowMod = await import(PACKAGE_NAME);
48
+ return _agenticowMod;
49
+ }
50
+ catch (err) {
51
+ if (err && (err.code === 'ERR_MODULE_NOT_FOUND' || err.code === 'MODULE_NOT_FOUND' ||
52
+ /Cannot find (module|package)/i.test(String(err.message)))) {
53
+ _agenticowMod = false;
54
+ return null;
55
+ }
56
+ throw err;
57
+ }
58
+ }
59
+ function degradedResult(reason) {
60
+ return { success: true, degraded: true, reason };
61
+ }
62
+ function resolveMemoryPath(path) {
63
+ if (!path || typeof path !== 'string')
64
+ throw new Error('memory path is required');
65
+ // D-2 style: reject path traversal in user-supplied paths
66
+ if (/\.\.[\\/]|\0/.test(path))
67
+ throw new Error('memory path contains disallowed characters');
68
+ return isAbsolute(path) ? path : resolve(getProjectCwd(), path);
69
+ }
70
+ /**
71
+ * Lineage manifest companion path. agenticow persists the COW chain
72
+ * (working → checkpoints → base) into `<file>.agenticow.json` next to the
73
+ * `.rvf` data file. Without this, checkpoints and forks are in-memory only
74
+ * and disappear when the AgenticMemory handle closes. Mirrors the bin
75
+ * CLI's `manifestFor(file)` helper.
76
+ */
77
+ function manifestFor(file) {
78
+ return `${file}.agenticow.json`;
79
+ }
80
+ function validateLabel(label) {
81
+ if (!label || typeof label !== 'string')
82
+ throw new Error('label is required');
83
+ if (label.length > 256)
84
+ throw new Error('label exceeds 256 chars');
85
+ if (!/^[A-Za-z0-9_.\-:/@]+$/.test(label)) {
86
+ throw new Error('label may only contain [A-Za-z0-9_.\\-:/@]');
87
+ }
88
+ return label;
89
+ }
90
+ /**
91
+ * Open (or create) a base memory file. When a lineage manifest exists at
92
+ * `<file>.agenticow.json`, we load that to restore the COW chain (checkpoints,
93
+ * ancestors). When only the `.rvf` exists, fresh-open it. When neither exists,
94
+ * dimension is required to create. Mirrors the bin CLI's `loadMem()` helper.
95
+ */
96
+ async function openWithLineage(api, file, dimension) {
97
+ const manifest = manifestFor(file);
98
+ if (existsSync(manifest)) {
99
+ // The class-level static method `load` reconstructs the full chain.
100
+ return api.AgenticMemory.load(manifest);
101
+ }
102
+ const opts = {};
103
+ if (typeof dimension === 'number' && Number.isInteger(dimension) && dimension > 0) {
104
+ opts.dimension = dimension;
105
+ }
106
+ else if (!existsSync(file)) {
107
+ throw new Error('dimension is required when creating a new memory file');
108
+ }
109
+ return api.open(file, opts);
110
+ }
111
+ export const agenticowTools = [
112
+ {
113
+ name: 'agenticow_branch',
114
+ description: 'agenticow@~0.2.3 — COW-fork a base .rvf memory file. Measured 162-byte branches regardless of base size (verified at N=1k/10k/50k). Use when you need per-Darwin-iteration / per-user / per-session memory personalization. Copying the parent .rvf file is wrong because full-copy snapshots grow linearly (the 3.3 GB Darwin-worktree bloat fixed in v3.14.4); agenticow gives read-through semantics (parent ∪ edits, child wins) at constant 162 B. Optional dep — degrades to {degraded:true} when missing.',
115
+ category: 'memory',
116
+ tags: ['agenticow', 'memory', 'cow', 'branch'],
117
+ inputSchema: {
118
+ type: 'object',
119
+ properties: {
120
+ basePath: { type: 'string', description: 'Path to base .rvf memory file (absolute or relative to cwd)' },
121
+ branchPath: { type: 'string', description: 'Path to write the branch file' },
122
+ label: { type: 'string', description: 'Human-readable label for the branch (alnum + _.-:/@ only)' },
123
+ dimension: { type: 'integer', description: 'Vector dimension (required only when basePath does not exist yet)' },
124
+ },
125
+ required: ['basePath', 'branchPath', 'label'],
126
+ },
127
+ handler: async (input) => {
128
+ const api = await loadAgenticow();
129
+ if (!api)
130
+ return degradedResult('agenticow-not-found');
131
+ const label = validateLabel(String(input.label));
132
+ const basePath = resolveMemoryPath(String(input.basePath));
133
+ const branchPath = resolveMemoryPath(String(input.branchPath));
134
+ const dim = input.dimension;
135
+ const base = await openWithLineage(api, basePath, dim);
136
+ try {
137
+ const branch = await base.fork(label, branchPath);
138
+ // Persist lineage manifests so the branch (and base) reopen with
139
+ // their COW chain intact. Without this, fork is in-memory only.
140
+ await branch.save?.(manifestFor(branchPath));
141
+ await base.save?.(manifestFor(basePath));
142
+ await branch.close?.();
143
+ return {
144
+ success: true,
145
+ basePath,
146
+ branchPath,
147
+ label,
148
+ };
149
+ }
150
+ finally {
151
+ await base.close?.();
152
+ }
153
+ },
154
+ },
155
+ {
156
+ name: 'agenticow_checkpoint',
157
+ description: 'agenticow — freeze a labelled restore point on an .rvf memory file. Subsequent edits stay in a fresh COW child; rollback returns here. Use when you are about to run an experimental Darwin tick or speculative agent edit that may need to be discarded. Relying on the working node alone is wrong because there is no "undo last N writes" semantics — without a checkpoint, a bad ingest contaminates the base. Persists via .agenticow.json lineage manifest so it survives close+reopen.',
158
+ category: 'memory',
159
+ tags: ['agenticow', 'memory', 'cow', 'checkpoint'],
160
+ inputSchema: {
161
+ type: 'object',
162
+ properties: {
163
+ path: { type: 'string', description: 'Path to .rvf memory file' },
164
+ label: { type: 'string', description: 'Checkpoint label (alnum + _.-:/@ only)' },
165
+ },
166
+ required: ['path', 'label'],
167
+ },
168
+ handler: async (input) => {
169
+ const api = await loadAgenticow();
170
+ if (!api)
171
+ return degradedResult('agenticow-not-found');
172
+ const label = validateLabel(String(input.label));
173
+ const path = resolveMemoryPath(String(input.path));
174
+ const mem = await openWithLineage(api, path);
175
+ try {
176
+ const cp = await mem.checkpoint(label);
177
+ await mem.save?.(manifestFor(path));
178
+ return { success: true, path, label, checkpoint: cp };
179
+ }
180
+ finally {
181
+ await mem.close?.();
182
+ }
183
+ },
184
+ },
185
+ {
186
+ name: 'agenticow_rollback',
187
+ description: 'agenticow — discard all edits since the most recent checkpoint on an .rvf memory file. Reuses a fresh COW child derived from the checkpoint. Use when a Darwin tick or agent experiment regressed and you want to revert memory state without re-running. Deleting+rebuilding the .rvf is wrong because rebuild cost is O(N) and the data after the bad point is lost; rollback is O(edits-since-checkpoint) and the earlier history stays intact via the lineage manifest.',
188
+ category: 'memory',
189
+ tags: ['agenticow', 'memory', 'cow', 'rollback'],
190
+ inputSchema: {
191
+ type: 'object',
192
+ properties: {
193
+ path: { type: 'string', description: 'Path to .rvf memory file' },
194
+ },
195
+ required: ['path'],
196
+ },
197
+ handler: async (input) => {
198
+ const api = await loadAgenticow();
199
+ if (!api)
200
+ return degradedResult('agenticow-not-found');
201
+ const path = resolveMemoryPath(String(input.path));
202
+ const mem = await openWithLineage(api, path);
203
+ try {
204
+ const r = await mem.rollback();
205
+ await mem.save?.(manifestFor(path));
206
+ return { success: true, path, rolledBack: true, result: r };
207
+ }
208
+ finally {
209
+ await mem.close?.();
210
+ }
211
+ },
212
+ },
213
+ {
214
+ name: 'agenticow_promote',
215
+ description: 'agenticow — merge a branch\'s edits back into its base (or an explicit target) memory file. After promote, branch edits become part of base lineage. Use when a per-user / per-Darwin-iteration branch has been validated and should graduate to shared memory (federation merge, A/B winner). Manually re-ingesting edits into the base is wrong because the edit set is opaque to the caller and tombstones (deletions) are easily missed; promote applies the full edit + tombstone set atomically.',
216
+ category: 'memory',
217
+ tags: ['agenticow', 'memory', 'cow', 'promote', 'merge'],
218
+ inputSchema: {
219
+ type: 'object',
220
+ properties: {
221
+ branchPath: { type: 'string', description: 'Path to branch .rvf file' },
222
+ basePath: {
223
+ type: 'string',
224
+ description: 'Path to base .rvf file. When omitted, promote merges into the ' +
225
+ 'recorded fork parent (most common case).',
226
+ },
227
+ },
228
+ required: ['branchPath'],
229
+ },
230
+ handler: async (input) => {
231
+ const api = await loadAgenticow();
232
+ if (!api)
233
+ return degradedResult('agenticow-not-found');
234
+ const branchPath = resolveMemoryPath(String(input.branchPath));
235
+ const basePath = input.basePath ? resolveMemoryPath(String(input.basePath)) : undefined;
236
+ const branch = await openWithLineage(api, branchPath);
237
+ const base = basePath ? await openWithLineage(api, basePath) : undefined;
238
+ try {
239
+ const result = base ? await branch.promote(base) : await branch.promote();
240
+ // Persist mutated lineage so promote survives close+reopen
241
+ await branch.save?.(manifestFor(branchPath));
242
+ if (base && basePath)
243
+ await base.save?.(manifestFor(basePath));
244
+ return { success: true, branchPath, basePath: basePath ?? null, promoted: result ?? true };
245
+ }
246
+ finally {
247
+ await branch.close?.();
248
+ await base?.close?.();
249
+ }
250
+ },
251
+ },
252
+ ];
253
+ //# sourceMappingURL=agenticow-tools.js.map
@@ -26,4 +26,5 @@ export { guidanceTools } from './guidance-tools.js';
26
26
  export { autopilotTools } from './autopilot-tools.js';
27
27
  export { metaharnessTools } from './metaharness-tools.js';
28
28
  export { testgenTools } from './testgen-tools.js';
29
+ export { agenticowTools } from './agenticow-tools.js';
29
30
  //# sourceMappingURL=index.d.ts.map
@@ -27,4 +27,6 @@ export { autopilotTools } from './autopilot-tools.js';
27
27
  export { metaharnessTools } from './metaharness-tools.js';
28
28
  // ADR-175-inspired — Test-Driven Repair via headless `claude -p`
29
29
  export { testgenTools } from './testgen-tools.js';
30
+ // agenticow@~0.2.3 — Copy-On-Write memory branching (162-byte branches)
31
+ export { agenticowTools } from './agenticow-tools.js';
30
32
  //# sourceMappingURL=index.js.map
@@ -18,6 +18,12 @@
18
18
  * - metaharness_security_bench upstream's "Darwin Shield" (their own ADR-155)
19
19
  * - metaharness_bench create/verify bench suites used by evolve --bench
20
20
  *
21
+ * @metaharness/redblue integration adds one tool that targets the standalone
22
+ * `@metaharness/redblue` npm package — adversarial red/blue LLM testing
23
+ * for the agents and apps you own:
24
+ *
25
+ * - metaharness_redblue red-team → judge → blue-patch → retest → report
26
+ *
21
27
  * Every tool resolves the corresponding plugin script
22
28
  * (`plugins/ruflo-metaharness/scripts/<X>.mjs`) via the same locator
23
29
  * the commands/metaharness.ts dispatcher uses, then spawns it with
@@ -18,6 +18,12 @@
18
18
  * - metaharness_security_bench upstream's "Darwin Shield" (their own ADR-155)
19
19
  * - metaharness_bench create/verify bench suites used by evolve --bench
20
20
  *
21
+ * @metaharness/redblue integration adds one tool that targets the standalone
22
+ * `@metaharness/redblue` npm package — adversarial red/blue LLM testing
23
+ * for the agents and apps you own:
24
+ *
25
+ * - metaharness_redblue red-team → judge → blue-patch → retest → report
26
+ *
21
27
  * Every tool resolves the corresponding plugin script
22
28
  * (`plugins/ruflo-metaharness/scripts/<X>.mjs`) via the same locator
23
29
  * the commands/metaharness.ts dispatcher uses, then spawns it with
@@ -42,8 +48,14 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
42
48
  /**
43
49
  * Walk up from this module to find plugins/ruflo-metaharness/scripts/.
44
50
  * Handles three install layouts (mirrors commands/metaharness.ts).
51
+ *
52
+ * `requiredScript`, if provided, narrows the match the same way the
53
+ * commands dispatcher does — guards against the publish-artifact mirror
54
+ * (`v3/@claude-flow/cli/plugins/ruflo-metaharness/scripts/`, regenerated
55
+ * by `prepublishOnly`) shadowing the source when it's stale on a new
56
+ * script.
45
57
  */
46
- function locatePluginScripts() {
58
+ function locatePluginScripts(requiredScript) {
47
59
  const candidates = [];
48
60
  let p = resolve(__dirname);
49
61
  for (let i = 0; i < 8; i++) {
@@ -55,8 +67,11 @@ function locatePluginScripts() {
55
67
  candidates.push(join(cwd, 'plugins', 'ruflo-metaharness', 'scripts'));
56
68
  candidates.push(join(cwd, 'node_modules', '@claude-flow', 'cli', 'plugins', 'ruflo-metaharness', 'scripts'));
57
69
  for (const c of candidates) {
58
- if (existsSync(join(c, '_harness.mjs')))
59
- return c;
70
+ if (!existsSync(join(c, '_harness.mjs')))
71
+ continue;
72
+ if (requiredScript && !existsSync(join(c, requiredScript)))
73
+ continue;
74
+ return c;
60
75
  }
61
76
  return null;
62
77
  }
@@ -90,7 +105,7 @@ function locatePluginScripts() {
90
105
  */
91
106
  function runScript(scriptName, args) {
92
107
  return new Promise((resolve) => {
93
- const dir = locatePluginScripts();
108
+ const dir = locatePluginScripts(scriptName);
94
109
  if (!dir) {
95
110
  resolve({
96
111
  exitCode: 0, stdout: '', json: { degraded: true, reason: 'plugin-not-found' },
@@ -512,5 +527,69 @@ export const metaharnessTools = [
512
527
  return { success: r.success, data: r.json, degraded: r.degraded, exitCode: r.exitCode };
513
528
  },
514
529
  },
530
+ // ───────────────────────────────────────────────────────────────────────
531
+ // @metaharness/redblue integration (1 tool).
532
+ // Backed by `@metaharness/redblue@~0.1.1`. Plugin script shells out via
533
+ // _redblue.mjs. Same {success, data, degraded, exitCode} contract.
534
+ //
535
+ // SAFETY: redblue itself enforces hard boundaries (no real creds, no live
536
+ // targets, no shell, no arbitrary network, no eval) in upstream's
537
+ // src/config/safety.ts at config-load time. The wrapper does NOT relax
538
+ // those — it only forwards argv with shell:false. `--mock-judge` is the
539
+ // $0 marker-fixture CI path; the real model judge requires
540
+ // $OPENROUTER_API_KEY which we never inject.
541
+ // ───────────────────────────────────────────────────────────────────────
542
+ {
543
+ name: 'metaharness_redblue',
544
+ description: 'Adversarial red/blue LLM testing via @metaharness/redblue — generates attacks across OWASP LLM Top-10 / NIST AI RMF families (prompt injection, tool misuse, data leakage, jailbreaks, denial-of-wallet), runs them against an LLM target YOU OWN, judges compromise, optionally applies declarative blue-team patches, retests, and emits a board-readable report with measured failure reduction. Use when shipping an LLM-powered product and you need a repeatable security gate before exposing it to users — eyeballing prompts is wrong because attack surface coverage requires the OWASP/NIST taxonomy and the judge has to be model-driven for jailbreak detection. SAFETY: upstream hard-enforces no-creds / no-live-targets / no-shell / no-network / no-eval at config-load time; cannot be relaxed via flags. For CI / offline use --mockJudge=true ($0 marker fixture). For real model judging set $OPENROUTER_API_KEY and accept the per-run cost capped by max_cost_usd (default $3). ' + MCP_SUCCESS_SEMANTIC,
545
+ category: 'metaharness',
546
+ inputSchema: {
547
+ type: 'object',
548
+ properties: {
549
+ subcommand: {
550
+ type: 'string',
551
+ enum: ['init', 'run', 'patch', 'attack', 'report'],
552
+ description: 'init = scaffold redblue.yaml; run = baseline (+ optional --patch); patch = baseline → patch → retest delta; attack = preview attacks; report = render existing report.json',
553
+ default: 'run',
554
+ },
555
+ config: { type: 'string', description: 'Path to redblue.yaml (default: ./redblue.yaml)' },
556
+ out: { type: 'string', description: 'Output report path for run/patch (default: temp file we read back inline)' },
557
+ in: { type: 'string', description: 'Input report path for `report` subcommand' },
558
+ tests: { type: 'number', description: 'How many test cases (run/patch only)' },
559
+ patch: { type: 'boolean', description: '`run` only — after baseline, apply blue-team patches and retest', default: false },
560
+ mockJudge: { type: 'boolean', description: '$0 TEST-ONLY marker fixture (no model calls). Use for CI / offline. Real judging requires OPENROUTER_API_KEY.', default: false },
561
+ family: { type: 'string', enum: ['prompt', 'tools', 'data', 'all'], description: '`attack` subcommand only — which attack family to preview' },
562
+ count: { type: 'number', description: '`attack` only — how many cases to preview' },
563
+ alertOnFail: { type: 'boolean', description: 'Exit 1 when post-patch verdict is FAIL (gate-style)', default: false },
564
+ timeoutMs: { type: 'number', description: 'Subprocess hard timeout (default 120000; mock-judge runs complete in seconds)' },
565
+ },
566
+ },
567
+ handler: async (input) => {
568
+ const args = [String(input.subcommand ?? 'run')];
569
+ // attack family is positional
570
+ if (input.subcommand === 'attack' && input.family)
571
+ args.push(String(input.family));
572
+ if (input.config)
573
+ args.push('--config', String(input.config));
574
+ if (input.out)
575
+ args.push('--out', String(input.out));
576
+ if (input.in)
577
+ args.push('--in', String(input.in));
578
+ if (input.tests !== undefined)
579
+ args.push('--tests', String(input.tests));
580
+ if (input.patch === true)
581
+ args.push('--patch');
582
+ if (input.mockJudge === true)
583
+ args.push('--mock-judge');
584
+ if (input.count !== undefined)
585
+ args.push('--count', String(input.count));
586
+ if (input.alertOnFail === true)
587
+ args.push('--alert-on-fail');
588
+ if (input.timeoutMs !== undefined)
589
+ args.push('--timeout-ms', String(input.timeoutMs));
590
+ const r = await runScript('redblue.mjs', args);
591
+ return { success: r.success, data: r.json, degraded: r.degraded, exitCode: r.exitCode };
592
+ },
593
+ },
515
594
  ];
516
595
  //# sourceMappingURL=metaharness-tools.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.14.4",
3
+ "version": "3.15.0",
4
4
  "type": "module",
5
5
  "description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",
@@ -106,6 +106,7 @@
106
106
  "yaml": "^2.8.0"
107
107
  },
108
108
  "optionalDependencies": {
109
+ "agenticow": "~0.2.3",
109
110
  "@claude-flow/aidefence": "^3.0.2",
110
111
  "@claude-flow/codex": "^3.0.0-alpha.8",
111
112
  "@claude-flow/embeddings": "^3.0.0-alpha.18",
@@ -115,6 +116,7 @@
115
116
  "@claude-flow/security": "^3.0.0-alpha.10",
116
117
  "@metaharness/darwin": "~0.3.1",
117
118
  "@metaharness/kernel": "~0.1.0",
119
+ "@metaharness/redblue": "~0.1.1",
118
120
  "@metaharness/router": "~0.3.2",
119
121
  "metaharness": "~0.2.6",
120
122
  "@ruvector/attention": "^0.1.32",