@claude-flow/cli 3.12.0 → 3.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/helpers/auto-memory-hook.mjs +34 -4
- package/.claude/helpers/hook-handler.cjs +17 -13
- package/.claude/helpers/intelligence.cjs +16 -2
- package/README.md +7 -4
- package/dist/src/commands/daemon.d.ts.map +1 -1
- package/dist/src/commands/daemon.js +76 -7
- package/dist/src/commands/daemon.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +24 -3
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/security.d.ts.map +1 -1
- package/dist/src/commands/security.js +70 -12
- package/dist/src/commands/security.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/plugins/ruflo-metaharness/.claude-flow/data/pending-insights.jsonl +1 -0
- package/plugins/ruflo-metaharness/.claude-flow/neural/stats.json +6 -0
- package/plugins/ruflo-metaharness/.claude-plugin/plugin.json +32 -0
- package/plugins/ruflo-metaharness/README.md +64 -0
- package/plugins/ruflo-metaharness/agents/metaharness-architect.md +58 -0
- package/plugins/ruflo-metaharness/commands/ruflo-metaharness.md +46 -0
- package/plugins/ruflo-metaharness/scripts/_harness.mjs +261 -0
- package/plugins/ruflo-metaharness/scripts/_similarity.mjs +161 -0
- package/plugins/ruflo-metaharness/scripts/_spike-similarity.mjs +223 -0
- package/plugins/ruflo-metaharness/scripts/audit-list.mjs +158 -0
- package/plugins/ruflo-metaharness/scripts/audit-trend.mjs +272 -0
- package/plugins/ruflo-metaharness/scripts/bench-parse-mcp-scan.mjs +146 -0
- package/plugins/ruflo-metaharness/scripts/bench-recordpair-overhead.mjs +186 -0
- package/plugins/ruflo-metaharness/scripts/bench-similarity.mjs +177 -0
- package/plugins/ruflo-metaharness/scripts/drift-from-history.mjs +363 -0
- package/plugins/ruflo-metaharness/scripts/genome.mjs +80 -0
- package/plugins/ruflo-metaharness/scripts/mcp-scan.mjs +111 -0
- package/plugins/ruflo-metaharness/scripts/mint.mjs +119 -0
- package/plugins/ruflo-metaharness/scripts/oia-audit.mjs +228 -0
- package/plugins/ruflo-metaharness/scripts/router-parallel-analyze.mjs +250 -0
- package/plugins/ruflo-metaharness/scripts/score.mjs +92 -0
- package/plugins/ruflo-metaharness/scripts/similarity.mjs +158 -0
- package/plugins/ruflo-metaharness/scripts/smoke.sh +2268 -0
- package/plugins/ruflo-metaharness/scripts/test-graceful-degradation.mjs +141 -0
- package/plugins/ruflo-metaharness/scripts/test-mcp-tools.mjs +437 -0
- package/plugins/ruflo-metaharness/scripts/test-parallel-pipeline.mjs +204 -0
- package/plugins/ruflo-metaharness/scripts/test-pipeline-roundtrip.mjs +586 -0
- package/plugins/ruflo-metaharness/scripts/test-similarity.mjs +334 -0
- package/plugins/ruflo-metaharness/scripts/test-with-openrouter.mjs +229 -0
- package/plugins/ruflo-metaharness/scripts/threat-model.mjs +59 -0
- package/plugins/ruflo-metaharness/skills/harness-drift-from-history/SKILL.md +65 -0
- package/plugins/ruflo-metaharness/skills/harness-genome/SKILL.md +54 -0
- package/plugins/ruflo-metaharness/skills/harness-mcp-scan/SKILL.md +47 -0
- package/plugins/ruflo-metaharness/skills/harness-mint/SKILL.md +72 -0
- package/plugins/ruflo-metaharness/skills/harness-oia-audit/SKILL.md +79 -0
- package/plugins/ruflo-metaharness/skills/harness-score/SKILL.md +66 -0
- package/plugins/ruflo-metaharness/skills/harness-similarity/SKILL.md +67 -0
- 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();
|