@claude-flow/cli 3.12.0 → 3.12.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 (39) hide show
  1. package/package.json +3 -2
  2. package/plugins/ruflo-metaharness/.claude-flow/data/pending-insights.jsonl +1 -0
  3. package/plugins/ruflo-metaharness/.claude-flow/neural/stats.json +6 -0
  4. package/plugins/ruflo-metaharness/.claude-plugin/plugin.json +32 -0
  5. package/plugins/ruflo-metaharness/README.md +64 -0
  6. package/plugins/ruflo-metaharness/agents/metaharness-architect.md +58 -0
  7. package/plugins/ruflo-metaharness/commands/ruflo-metaharness.md +46 -0
  8. package/plugins/ruflo-metaharness/scripts/_harness.mjs +261 -0
  9. package/plugins/ruflo-metaharness/scripts/_similarity.mjs +161 -0
  10. package/plugins/ruflo-metaharness/scripts/_spike-similarity.mjs +223 -0
  11. package/plugins/ruflo-metaharness/scripts/audit-list.mjs +158 -0
  12. package/plugins/ruflo-metaharness/scripts/audit-trend.mjs +272 -0
  13. package/plugins/ruflo-metaharness/scripts/bench-parse-mcp-scan.mjs +146 -0
  14. package/plugins/ruflo-metaharness/scripts/bench-recordpair-overhead.mjs +186 -0
  15. package/plugins/ruflo-metaharness/scripts/bench-similarity.mjs +177 -0
  16. package/plugins/ruflo-metaharness/scripts/drift-from-history.mjs +363 -0
  17. package/plugins/ruflo-metaharness/scripts/genome.mjs +80 -0
  18. package/plugins/ruflo-metaharness/scripts/mcp-scan.mjs +111 -0
  19. package/plugins/ruflo-metaharness/scripts/mint.mjs +119 -0
  20. package/plugins/ruflo-metaharness/scripts/oia-audit.mjs +228 -0
  21. package/plugins/ruflo-metaharness/scripts/router-parallel-analyze.mjs +250 -0
  22. package/plugins/ruflo-metaharness/scripts/score.mjs +92 -0
  23. package/plugins/ruflo-metaharness/scripts/similarity.mjs +158 -0
  24. package/plugins/ruflo-metaharness/scripts/smoke.sh +2268 -0
  25. package/plugins/ruflo-metaharness/scripts/test-graceful-degradation.mjs +141 -0
  26. package/plugins/ruflo-metaharness/scripts/test-mcp-tools.mjs +437 -0
  27. package/plugins/ruflo-metaharness/scripts/test-parallel-pipeline.mjs +204 -0
  28. package/plugins/ruflo-metaharness/scripts/test-pipeline-roundtrip.mjs +586 -0
  29. package/plugins/ruflo-metaharness/scripts/test-similarity.mjs +334 -0
  30. package/plugins/ruflo-metaharness/scripts/test-with-openrouter.mjs +229 -0
  31. package/plugins/ruflo-metaharness/scripts/threat-model.mjs +59 -0
  32. package/plugins/ruflo-metaharness/skills/harness-drift-from-history/SKILL.md +65 -0
  33. package/plugins/ruflo-metaharness/skills/harness-genome/SKILL.md +54 -0
  34. package/plugins/ruflo-metaharness/skills/harness-mcp-scan/SKILL.md +47 -0
  35. package/plugins/ruflo-metaharness/skills/harness-mint/SKILL.md +72 -0
  36. package/plugins/ruflo-metaharness/skills/harness-oia-audit/SKILL.md +79 -0
  37. package/plugins/ruflo-metaharness/skills/harness-score/SKILL.md +66 -0
  38. package/plugins/ruflo-metaharness/skills/harness-similarity/SKILL.md +67 -0
  39. package/plugins/ruflo-metaharness/skills/harness-threat-model/SKILL.md +39 -0
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+ // similarity.mjs — ADR-152 §3.1 CLI skill.
3
+ //
4
+ // Computes weighted similarity between two harness fingerprints (genome
5
+ // + score JSON). Production-grade companion to _spike-similarity.mjs.
6
+ //
7
+ // USAGE
8
+ // node scripts/similarity.mjs --a a.json --b b.json
9
+ // node scripts/similarity.mjs --a-key harness-X --b-key harness-Y # memory lookup
10
+ // node scripts/similarity.mjs --a a.json --b b.json --per-dimension # breakdown
11
+ // node scripts/similarity.mjs --a a.json --b b.json --format json
12
+ // node scripts/similarity.mjs --a a.json --b b.json --alert-below 0.5 # exit 1 if low
13
+ //
14
+ // EXIT CODES
15
+ // 0 ok (or overall ≥ alert-below threshold)
16
+ // 1 --alert-below AND overall < threshold
17
+ // 2 config / input error (missing args, file not found, malformed JSON)
18
+ //
19
+ // ADR-150 ARCHITECTURAL CONSTRAINTS PRESERVED
20
+ // - Pure-TS function (`_similarity.mjs`), no `@metaharness/*` import
21
+ // - No new dep; uses node:fs + node:child_process only for memory lookup
22
+ // - Graceful degradation: missing keys / malformed JSON → exit 2 with
23
+ // a structured `{ degraded: true, reason: ... }` payload on stdout
24
+ // - CI-gate ready: smoke step 17y locks this contract
25
+
26
+ import { readFileSync, existsSync } from 'node:fs';
27
+ import { spawnSync } from 'node:child_process';
28
+ import { similarity } from './_similarity.mjs';
29
+
30
+ const NS = process.env.HARNESS_SIMILARITY_NAMESPACE || 'metaharness-audit';
31
+ const CLI_PKG = process.env.CLI_CORE === '1'
32
+ ? '@claude-flow/cli-core@alpha'
33
+ : '@claude-flow/cli@latest';
34
+
35
+ const ARGS = (() => {
36
+ const a = {
37
+ aFile: null, bFile: null,
38
+ aKey: null, bKey: null,
39
+ perDimension: false,
40
+ format: 'table',
41
+ alertBelow: null,
42
+ };
43
+ for (let i = 2; i < process.argv.length; i++) {
44
+ const v = process.argv[i];
45
+ if (v === '--a') a.aFile = process.argv[++i];
46
+ else if (v === '--b') a.bFile = process.argv[++i];
47
+ else if (v === '--a-key') a.aKey = process.argv[++i];
48
+ else if (v === '--b-key') a.bKey = process.argv[++i];
49
+ else if (v === '--per-dimension') a.perDimension = true;
50
+ else if (v === '--format') a.format = process.argv[++i];
51
+ else if (v === '--alert-below') a.alertBelow = Number(process.argv[++i]);
52
+ }
53
+ return a;
54
+ })();
55
+
56
+ function emitDegradedAndExit(reason, code = 2) {
57
+ const payload = {
58
+ degraded: true,
59
+ reason,
60
+ adr: 'ADR-152',
61
+ skill: 'harness-similarity',
62
+ generatedAt: new Date().toISOString(),
63
+ };
64
+ console.log(JSON.stringify(payload, null, 2));
65
+ process.exit(code);
66
+ }
67
+
68
+ function memRetrieve(key) {
69
+ const r = spawnSync('npx', [
70
+ CLI_PKG, 'memory', 'retrieve',
71
+ '--namespace', NS, '--key', key,
72
+ ], { stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf-8', shell: process.platform === 'win32' });
73
+ if (r.status !== 0) return null;
74
+ const m = /\{[\s\S]*\}/.exec(r.stdout || '');
75
+ if (!m) return null;
76
+ try { return JSON.parse(m[0]); } catch { return null; }
77
+ }
78
+
79
+ function loadHarness(label, filePath, memKey) {
80
+ if (filePath) {
81
+ if (!existsSync(filePath)) emitDegradedAndExit(`${label}: file not found: ${filePath}`);
82
+ try { return JSON.parse(readFileSync(filePath, 'utf-8')); }
83
+ catch (e) { emitDegradedAndExit(`${label}: invalid JSON: ${e.message}`); }
84
+ }
85
+ if (memKey) {
86
+ const rec = memRetrieve(memKey);
87
+ if (!rec) emitDegradedAndExit(`${label}: key not found in namespace ${NS}: ${memKey}`);
88
+ return rec;
89
+ }
90
+ emitDegradedAndExit(`${label}: --${label} or --${label}-key required`);
91
+ return null; // unreachable; emitDegradedAndExit exits
92
+ }
93
+
94
+ function main() {
95
+ if (!ARGS.aFile && !ARGS.aKey) emitDegradedAndExit('--a <file> or --a-key <memkey> required');
96
+ if (!ARGS.bFile && !ARGS.bKey) emitDegradedAndExit('--b <file> or --b-key <memkey> required');
97
+
98
+ const a = loadHarness('a', ARGS.aFile, ARGS.aKey);
99
+ const b = loadHarness('b', ARGS.bFile, ARGS.bKey);
100
+
101
+ const result = similarity(a, b, { perDimension: ARGS.perDimension });
102
+
103
+ const payload = {
104
+ adr: 'ADR-152',
105
+ skill: 'harness-similarity',
106
+ inputs: {
107
+ a: ARGS.aFile ?? `mem:${ARGS.aKey}`,
108
+ b: ARGS.bFile ?? `mem:${ARGS.bKey}`,
109
+ },
110
+ ...result,
111
+ alert: ARGS.alertBelow != null ? {
112
+ threshold: ARGS.alertBelow,
113
+ triggered: result.overall < ARGS.alertBelow,
114
+ reason: result.overall < ARGS.alertBelow
115
+ ? `overall ${result.overall} < threshold ${ARGS.alertBelow}`
116
+ : `overall ${result.overall} ≥ threshold ${ARGS.alertBelow}`,
117
+ } : null,
118
+ generatedAt: new Date().toISOString(),
119
+ };
120
+
121
+ if (ARGS.format === 'json') {
122
+ console.log(JSON.stringify(payload, null, 2));
123
+ } else {
124
+ console.log(`# harness similarity (ADR-152)\n`);
125
+ console.log(`Inputs:`);
126
+ console.log(` a: ${payload.inputs.a}`);
127
+ console.log(` b: ${payload.inputs.b}`);
128
+ console.log('');
129
+ console.log(`| Component | Score | Weight | Contribution |`);
130
+ console.log(`|-------------|-------:|-------:|-------------:|`);
131
+ const { weights, components } = payload;
132
+ console.log(`| cosine | ${components.cosine.toFixed(4)} | ${weights.cosine} | ${(components.cosine * weights.cosine).toFixed(4)} |`);
133
+ console.log(`| categorical | ${components.categorical.toFixed(4)} | ${weights.categorical} | ${(components.categorical * weights.categorical).toFixed(4)} |`);
134
+ console.log(`| jaccard | ${components.jaccard.toFixed(4)} | ${weights.jaccard} | ${(components.jaccard * weights.jaccard).toFixed(4)} |`);
135
+ console.log('');
136
+ console.log(`**Overall:** ${payload.overall.toFixed(4)}`);
137
+ if (payload.alert) {
138
+ console.log('');
139
+ console.log(payload.alert.triggered ? `⚠ ALERT: ${payload.alert.reason}` : `✓ ${payload.alert.reason}`);
140
+ }
141
+ if (ARGS.perDimension && payload.perDimension) {
142
+ console.log('');
143
+ console.log('## Per-dimension breakdown');
144
+ console.log('');
145
+ console.log('| Dimension | a | b | contribution |');
146
+ console.log('|---|---|---|---:|');
147
+ for (const [k, v] of Object.entries(payload.perDimension)) {
148
+ const av = Array.isArray(v.a) ? `[${v.a.join(',')}]` : String(v.a ?? '-');
149
+ const bv = Array.isArray(v.b) ? `[${v.b.join(',')}]` : String(v.b ?? '-');
150
+ console.log(`| ${k} | ${av} | ${bv} | ${Number(v.contribution).toFixed(4)} |`);
151
+ }
152
+ }
153
+ }
154
+
155
+ if (payload.alert?.triggered) process.exit(1);
156
+ }
157
+
158
+ main();