@claude-flow/cli 3.73.0 → 3.74.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/.claude/helpers/helpers.manifest.json +2 -2
  2. package/catalog-manifest.json +2 -2
  3. package/dist/src/commands/doctor.js +5 -3
  4. package/dist/src/mcp-tools/memory-tools.js +17 -0
  5. package/dist/src/mcp-tools/metaharness-tools.js +19 -0
  6. package/dist/src/memory/memory-bridge.d.ts +2 -0
  7. package/dist/src/memory/memory-bridge.js +1 -1
  8. package/dist/src/memory/memory-initializer.d.ts +2 -0
  9. package/dist/src/memory/memory-initializer.js +1 -1
  10. package/dist/src/metaharness/darwin-lib.d.ts +68 -0
  11. package/dist/src/metaharness/darwin-lib.js +150 -0
  12. package/dist/src/missions/schemas.d.ts +117 -117
  13. package/dist/src/mods/command-registry/schema.d.ts +121 -121
  14. package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
  15. package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
  16. package/node_modules/@claude-flow/security/dist/input-validator.d.ts +138 -106
  17. package/node_modules/@claude-flow/security/dist/input-validator.d.ts.map +1 -1
  18. package/node_modules/@claude-flow/security/dist/input-validator.js +23 -26
  19. package/node_modules/@claude-flow/security/dist/input-validator.js.map +1 -1
  20. package/node_modules/@claude-flow/security/package.json +2 -2
  21. package/package.json +6 -6
  22. package/plugins/ruflo-metaharness/.claude-plugin/plugin.json +1 -1
  23. package/plugins/ruflo-metaharness/CHANGELOG.md +3 -0
  24. package/plugins/ruflo-metaharness/scripts/_darwin.mjs +13 -0
  25. package/plugins/ruflo-metaharness/scripts/bench.mjs +34 -2
  26. package/plugins/ruflo-metaharness/scripts/smoke.sh +4 -4
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": {
3
- "version": "3.73.0",
3
+ "version": "3.74.1",
4
4
  "files": {
5
5
  "auto-memory-hook.mjs": "6078bd1c6b02dd3f80097f8d7f28904d48b3cdf7a534d2aa13966590694ca403",
6
6
  "hook-handler.cjs": "31db0f7492fbd8b2e48ea9adbc1ba293dfed1e006666d20e93ea76e158986947",
@@ -10,6 +10,6 @@
10
10
  "learning-loop.cjs": "d046cd6f8efb7dd40e1d2451516c181fc8b26477aefb1124c0df5f52a23f9190"
11
11
  }
12
12
  },
13
- "signature": "JPs8pGUFfkmmIj+GpqM7snJ1AX9IJS8olXiwHgZjSTKCIcK0aERAd+Wjy3jfBbK1V8mqP+ZWeX8CRr4aA+3BDA==",
13
+ "signature": "m7PiBVjpmQ0IvydivjKnvxzOUnRfRuhGTSZfJrJG+RPI8tfTTEU5Ah2knCTHXF/fTwdAiCEvzJvLf1vBv9fdCA==",
14
14
  "algorithm": "ed25519"
15
15
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "generation": 7,
4
- "generatedAt": "2026-11-09T01:20:38.869Z",
5
- "gitSha": "a8b3304b",
4
+ "generatedAt": "2026-11-09T06:36:19.466Z",
5
+ "gitSha": "2d590fc0",
6
6
  "catalog": {
7
7
  "agents": 177,
8
8
  "tools": 451,
@@ -2214,13 +2214,15 @@ async function checkMetaharnessDeclaredPackages() {
2214
2214
  if (!root)
2215
2215
  return { name: NAME, status: 'warn', message: 'could not locate the @claude-flow/cli package root' };
2216
2216
  const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8'));
2217
- const declared = Object.keys(pkg.optionalDependencies ?? {}).filter((n) => n === 'metaharness' || n.startsWith('@metaharness/'));
2217
+ // ADR-526: @metaharness/darwin is a regular dependency; the rest stay optional.
2218
+ const declared = Object.keys({ ...(pkg.dependencies ?? {}), ...(pkg.optionalDependencies ?? {}) })
2219
+ .filter((n) => n === 'metaharness' || n.startsWith('@metaharness/'));
2218
2220
  if (declared.length === 0) {
2219
2221
  return {
2220
2222
  name: NAME,
2221
2223
  status: 'fail',
2222
- message: 'no @metaharness/* packages declared in optionalDependencies — the dependency contract regressed (peer-only declarations are never installed)',
2223
- fix: 'Restore @metaharness/darwin, @metaharness/flywheel, @metaharness/radio, @metaharness/turn-credit to optionalDependencies in @claude-flow/cli',
2224
+ message: 'no @metaharness/* packages declared in dependencies or optionalDependencies — the dependency contract regressed (peer-only declarations are never installed)',
2225
+ fix: 'Restore @metaharness/darwin to dependencies and @metaharness/flywheel, @metaharness/radio, @metaharness/turn-credit to optionalDependencies in @claude-flow/cli',
2224
2226
  };
2225
2227
  }
2226
2228
  // Node resolution: nearest node_modules wins, walking upward from the CLI root.
@@ -434,6 +434,10 @@ export const memoryTools = [
434
434
  items: { type: 'string' },
435
435
  description: 'Optional tags for filtering',
436
436
  },
437
+ metadata: {
438
+ type: 'object',
439
+ description: 'Optional JSON object stored with the entry (e.g. { confidence: 0.9 }, which AutoMemoryBridge reads for sync eligibility). Replaces any existing metadata on upsert.',
440
+ },
437
441
  ttl: { type: 'number', description: 'Time-to-live in seconds (optional)' },
438
442
  upsert: { type: 'boolean', description: 'Update existing key instead of failing (default: true, matching CLI `memory store`; set false for strict-insert). #2775 parity.' },
439
443
  provenance_type: {
@@ -465,6 +469,18 @@ export const memoryTools = [
465
469
  // ADR-323: leave undefined when omitted so storeEntry's own default
466
470
  // ('unknown') applies uniformly across the CLI, MCP tool, and other callers.
467
471
  const provenanceType = input.provenance_type;
472
+ // #1426: metadata must be a plain JSON object; reject arrays, null and scalars.
473
+ const rawMetadata = input.metadata;
474
+ if (rawMetadata !== undefined && (typeof rawMetadata !== 'object' || rawMetadata === null || Array.isArray(rawMetadata))) {
475
+ return {
476
+ success: false,
477
+ key,
478
+ stored: false,
479
+ hasEmbedding: false,
480
+ error: 'metadata must be a JSON object',
481
+ };
482
+ }
483
+ const metadata = rawMetadata;
468
484
  if (!value) {
469
485
  return {
470
486
  success: false,
@@ -488,6 +504,7 @@ export const memoryTools = [
488
504
  namespace,
489
505
  generateEmbeddingFlag: true,
490
506
  tags,
507
+ metadata,
491
508
  ttl,
492
509
  upsert,
493
510
  provenanceType,
@@ -54,6 +54,7 @@ import { fileURLToPath } from 'node:url';
54
54
  import { homedir } from 'node:os';
55
55
  import { ownPluginDirs } from '../plugins/own-install.js';
56
56
  import { runFlywheelWorker } from '../services/harness-flywheel-runtime.js';
57
+ import { benchVerify, gepaOp } from '../metaharness/darwin-lib.js';
57
58
  import { evaluatePolicyRequest } from '../services/policy-runtime.js';
58
59
  import { listFlywheelReceipts, promoteFlywheelCandidate, readFlywheelTransactionState, resetSequentialEvidence, verifyFlywheelLedger, } from '../services/flywheel-transaction.js';
59
60
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -523,6 +524,13 @@ export const metaharnessTools = [
523
524
  required: ['op'],
524
525
  },
525
526
  handler: async (input) => {
527
+ // ADR-526: verify runs in-process (darwin is a regular dependency);
528
+ // create still goes through the darwin CLI, which owns the scaffold task.
529
+ if (input.op === 'verify') {
530
+ const inProc = await benchVerify(String(input.suite ?? ''));
531
+ if (inProc)
532
+ return { success: inProc.exitCode === 0, data: inProc.json, degraded: false, exitCode: inProc.exitCode };
533
+ }
526
534
  const args = ['--op', String(input.op)];
527
535
  if (input.repo)
528
536
  args.push('--repo', String(input.repo));
@@ -665,6 +673,17 @@ export const metaharnessTools = [
665
673
  required: ['op'],
666
674
  },
667
675
  handler: async (input) => {
676
+ // ADR-526: GEPA genome ops run in-process; the plugin script is the fallback.
677
+ const inProc = await gepaOp({
678
+ op: String(input.op),
679
+ path: input.path ? String(input.path) : undefined,
680
+ transcript: input.transcript ? String(input.transcript) : undefined,
681
+ ext: input.ext ? String(input.ext) : undefined,
682
+ glob: input.glob ? String(input.glob) : undefined,
683
+ alertOnInvalid: input.alertOnInvalid === true,
684
+ });
685
+ if (inProc)
686
+ return { success: inProc.exitCode === 0, data: inProc.json, degraded: false, exitCode: inProc.exitCode };
668
687
  const args = ['--op', String(input.op)];
669
688
  if (input.path)
670
689
  args.push('--path', String(input.path));
@@ -74,6 +74,8 @@ export declare function bridgeStoreEntry(options: {
74
74
  namespace?: string;
75
75
  generateEmbeddingFlag?: boolean;
76
76
  tags?: string[];
77
+ /** #1426: JSON object persisted to the metadata column. */
78
+ metadata?: Record<string, unknown>;
77
79
  ttl?: number;
78
80
  dbPath?: string;
79
81
  upsert?: boolean;
@@ -1182,7 +1182,7 @@ export async function bridgeStoreEntry(options) {
1182
1182
  }
1183
1183
  catch { /* vector_indexes may not exist on legacy DBs — fall through */ }
1184
1184
  const stmt = ctx.db.prepare(insertSql);
1185
- const insert = () => stmt.run(id, key, namespace, value, embeddingJson, dimensions || null, model, tags.length > 0 ? JSON.stringify(tags) : null, '{}', provenanceType, now, now, ttl ? now + (ttl * 1000) : null);
1185
+ const insert = () => stmt.run(id, key, namespace, value, embeddingJson, dimensions || null, model, tags.length > 0 ? JSON.stringify(tags) : null, JSON.stringify(options.metadata ?? {}), provenanceType, now, now, ttl ? now + (ttl * 1000) : null);
1186
1186
  let runResult;
1187
1187
  try {
1188
1188
  runResult = options.appendOnly
@@ -444,6 +444,8 @@ export declare function storeEntry(options: {
444
444
  namespace?: string;
445
445
  generateEmbeddingFlag?: boolean;
446
446
  tags?: string[];
447
+ /** #1426: JSON object persisted to the metadata column. */
448
+ metadata?: Record<string, unknown>;
447
449
  ttl?: number;
448
450
  dbPath?: string;
449
451
  upsert?: boolean;
@@ -2733,7 +2733,7 @@ export async function storeEntry(options) {
2733
2733
  embeddingDimensions,
2734
2734
  embeddingModel,
2735
2735
  tags.length > 0 ? JSON.stringify(tags) : null,
2736
- '{}',
2736
+ JSON.stringify(options.metadata ?? {}),
2737
2737
  persistedProvenance,
2738
2738
  now,
2739
2739
  now,
@@ -0,0 +1,68 @@
1
+ /**
2
+ * In-process access to @metaharness/darwin (ADR-526).
3
+ *
4
+ * darwin is a regular dependency of the CLI, so the long-lived MCP server can
5
+ * import it once and answer `metaharness_bench --op verify` and every
6
+ * `metaharness_gepa` op without spawning `node bench.mjs` → `node darwin/cli.js`
7
+ * per call. Each function returns the same {exitCode, json} pair the plugin
8
+ * script would have produced, so callers keep the existing
9
+ * {success, data, degraded, exitCode} contract.
10
+ *
11
+ * Graceful degradation (ADR-150 rule 3) still holds: if the import fails, every
12
+ * function returns null and the caller falls back to the subprocess path.
13
+ */
14
+ import { readFileSync } from 'node:fs';
15
+ export interface DarwinResult {
16
+ exitCode: number;
17
+ /** Parsed payload, or null where the script would have printed only to stderr. */
18
+ json: unknown;
19
+ }
20
+ type DarwinRoot = {
21
+ bench: {
22
+ loadSuite(path: string): Promise<{
23
+ id: string;
24
+ version: string;
25
+ tasks: unknown[];
26
+ }>;
27
+ verifySuite(suite: unknown): {
28
+ ok: boolean;
29
+ actual: string;
30
+ };
31
+ };
32
+ };
33
+ type DarwinGepa = {
34
+ loadGenome(read: typeof readFileSync, path: string): unknown;
35
+ loadCand6Genome(): unknown;
36
+ validateGenome(genome: unknown): unknown[];
37
+ buildSystemFromGenome(genome: unknown, ext?: string, glob?: string): string;
38
+ analyzeTranscript(entries: unknown[]): unknown;
39
+ CAND6_GENOME_PATH: string;
40
+ };
41
+ export declare function loadDarwin(): Promise<DarwinRoot | null>;
42
+ export declare function loadDarwinGepa(): Promise<DarwinGepa | null>;
43
+ /** Test hook: forget the cached modules. */
44
+ export declare function resetDarwinCache(): void;
45
+ /**
46
+ * `bench verify <suite>` in-process. Mirrors plugins/ruflo-metaharness/scripts/bench.mjs:
47
+ * exit 2 + no payload for a missing path, exit 1 when the suite fails to load
48
+ * (darwin's loadSuite throws on tamper) or its hash does not match, exit 0 otherwise.
49
+ * Returns null when darwin cannot be imported.
50
+ */
51
+ export declare function benchVerify(suitePath: string): Promise<DarwinResult | null>;
52
+ export interface GepaInput {
53
+ op: string;
54
+ path?: string;
55
+ transcript?: string;
56
+ ext?: string;
57
+ glob?: string;
58
+ alertOnInvalid?: boolean;
59
+ }
60
+ /**
61
+ * GEPA genome ops in-process. Mirrors plugins/ruflo-metaharness/scripts/gepa.mjs,
62
+ * including its exit codes: 2 for input errors (no payload), 1 for an invalid
63
+ * genome with alertOnInvalid, 0 otherwise. Returns null when darwin/gepa cannot
64
+ * be imported.
65
+ */
66
+ export declare function gepaOp(input: GepaInput): Promise<DarwinResult | null>;
67
+ export {};
68
+ //# sourceMappingURL=darwin-lib.d.ts.map
@@ -0,0 +1,150 @@
1
+ /**
2
+ * In-process access to @metaharness/darwin (ADR-526).
3
+ *
4
+ * darwin is a regular dependency of the CLI, so the long-lived MCP server can
5
+ * import it once and answer `metaharness_bench --op verify` and every
6
+ * `metaharness_gepa` op without spawning `node bench.mjs` → `node darwin/cli.js`
7
+ * per call. Each function returns the same {exitCode, json} pair the plugin
8
+ * script would have produced, so callers keep the existing
9
+ * {success, data, degraded, exitCode} contract.
10
+ *
11
+ * Graceful degradation (ADR-150 rule 3) still holds: if the import fails, every
12
+ * function returns null and the caller falls back to the subprocess path.
13
+ */
14
+ import { existsSync, readFileSync } from 'node:fs';
15
+ import { resolve } from 'node:path';
16
+ // The specifiers are held in variables so a missing package degrades at
17
+ // runtime instead of failing the CLI's own type-check or bundling.
18
+ const ROOT_SPEC = '@metaharness/darwin';
19
+ const GEPA_SPEC = '@metaharness/darwin/gepa';
20
+ let rootPromise = null;
21
+ let gepaPromise = null;
22
+ export function loadDarwin() {
23
+ rootPromise ??= import(ROOT_SPEC).then((m) => m, () => null);
24
+ return rootPromise;
25
+ }
26
+ export function loadDarwinGepa() {
27
+ gepaPromise ??= import(GEPA_SPEC).then((m) => m, () => null);
28
+ return gepaPromise;
29
+ }
30
+ /** Test hook: forget the cached modules. */
31
+ export function resetDarwinCache() {
32
+ rootPromise = null;
33
+ gepaPromise = null;
34
+ }
35
+ /**
36
+ * `bench verify <suite>` in-process. Mirrors plugins/ruflo-metaharness/scripts/bench.mjs:
37
+ * exit 2 + no payload for a missing path, exit 1 when the suite fails to load
38
+ * (darwin's loadSuite throws on tamper) or its hash does not match, exit 0 otherwise.
39
+ * Returns null when darwin cannot be imported.
40
+ */
41
+ export async function benchVerify(suitePath) {
42
+ const darwin = await loadDarwin();
43
+ if (!darwin)
44
+ return null;
45
+ if (!suitePath || !existsSync(resolve(suitePath)))
46
+ return { exitCode: 2, json: null };
47
+ const start = Date.now();
48
+ const file = resolve(suitePath);
49
+ try {
50
+ const suite = await darwin.bench.loadSuite(file);
51
+ const check = darwin.bench.verifySuite(suite);
52
+ const tasks = Array.isArray(suite.tasks) ? suite.tasks.length : 0;
53
+ const data = {
54
+ op: 'verify',
55
+ suiteId: suite.id,
56
+ version: suite.version,
57
+ tasks,
58
+ hashOk: check.ok,
59
+ hash: check.actual,
60
+ // Same line the darwin CLI prints, so readers of the old shape keep working.
61
+ stdoutTail: `Suite ${suite.id}@${suite.version}: ${tasks} tasks, hash ${check.ok ? 'OK' : 'MISMATCH'} (${String(check.actual).slice(0, 12)}…)\n`,
62
+ durationMs: Date.now() - start,
63
+ };
64
+ return { exitCode: check.ok ? 0 : 1, json: { success: check.ok, data, generatedAt: new Date().toISOString() } };
65
+ }
66
+ catch (e) {
67
+ const data = { op: 'verify', error: e instanceof Error ? e.message : String(e), durationMs: Date.now() - start };
68
+ return { exitCode: 1, json: { success: false, data, generatedAt: new Date().toISOString() } };
69
+ }
70
+ }
71
+ const GEPA_OPS = ['genome', 'validate', 'render', 'analyze'];
72
+ function readJson(path) {
73
+ try {
74
+ return { ok: true, value: JSON.parse(readFileSync(path, 'utf8')) };
75
+ }
76
+ catch {
77
+ return { ok: false };
78
+ }
79
+ }
80
+ /**
81
+ * GEPA genome ops in-process. Mirrors plugins/ruflo-metaharness/scripts/gepa.mjs,
82
+ * including its exit codes: 2 for input errors (no payload), 1 for an invalid
83
+ * genome with alertOnInvalid, 0 otherwise. Returns null when darwin/gepa cannot
84
+ * be imported.
85
+ */
86
+ export async function gepaOp(input) {
87
+ if (!GEPA_OPS.includes(input.op))
88
+ return { exitCode: 2, json: null };
89
+ const gepa = await loadDarwinGepa();
90
+ if (!gepa)
91
+ return null;
92
+ const start = Date.now();
93
+ let out;
94
+ try {
95
+ const loadGenome = () => {
96
+ if (input.path) {
97
+ if (!existsSync(input.path))
98
+ return null;
99
+ return { genome: gepa.loadGenome(readFileSync, input.path), source: input.path };
100
+ }
101
+ return { genome: gepa.loadCand6Genome(), source: gepa.CAND6_GENOME_PATH };
102
+ };
103
+ if (input.op === 'genome') {
104
+ const loaded = loadGenome();
105
+ if (!loaded)
106
+ return { exitCode: 2, json: null };
107
+ const errors = gepa.validateGenome(loaded.genome);
108
+ out = { op: 'genome', source: loaded.source, valid: errors.length === 0, errors, genome: loaded.genome };
109
+ }
110
+ else if (input.op === 'validate') {
111
+ let raw;
112
+ if (input.path) {
113
+ if (!existsSync(input.path))
114
+ return { exitCode: 2, json: null };
115
+ const r = readJson(input.path);
116
+ if (!r.ok)
117
+ return { exitCode: 2, json: null };
118
+ raw = r.value;
119
+ }
120
+ else {
121
+ raw = gepa.loadCand6Genome();
122
+ }
123
+ const errors = gepa.validateGenome(raw);
124
+ out = { op: 'validate', source: input.path ?? gepa.CAND6_GENOME_PATH, valid: errors.length === 0, errors };
125
+ }
126
+ else if (input.op === 'render') {
127
+ const loaded = loadGenome();
128
+ if (!loaded)
129
+ return { exitCode: 2, json: null };
130
+ const system = gepa.buildSystemFromGenome(loaded.genome, input.ext, input.glob);
131
+ out = { op: 'render', source: loaded.source, chars: system.length, system };
132
+ }
133
+ else {
134
+ if (!input.transcript || !existsSync(input.transcript))
135
+ return { exitCode: 2, json: null };
136
+ const r = readJson(input.transcript);
137
+ if (!r.ok || !Array.isArray(r.value))
138
+ return { exitCode: 2, json: null };
139
+ out = { op: 'analyze', source: input.transcript, entries: r.value.length, analysis: gepa.analyzeTranscript(r.value) };
140
+ }
141
+ }
142
+ catch {
143
+ // gepa.mjs exits 2 on any thrown error (its main().catch handler).
144
+ return { exitCode: 2, json: null };
145
+ }
146
+ out.durationMs = Date.now() - start;
147
+ const exitCode = input.alertOnInvalid && out.valid === false ? 1 : 0;
148
+ return { exitCode, json: out };
149
+ }
150
+ //# sourceMappingURL=darwin-lib.js.map