@claude-flow/cli 3.56.10 → 3.57.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.
- package/.claude/helpers/.helpers-version +1 -1
- package/.claude/helpers/helpers.manifest.json +2 -2
- package/README.md +12 -3
- package/catalog-manifest.json +2 -2
- package/dist/src/commands/daemon.js +8 -2
- package/dist/src/commands/doctor.js +95 -18
- package/dist/src/commands/policy.js +6 -1
- package/dist/src/index.js +5 -5
- package/dist/src/init/settings-generator.js +4 -58
- package/dist/src/mcp-tools/memory-tools.d.ts +1 -1
- package/dist/src/mcp-tools/memory-tools.js +30 -5
- package/dist/src/mcp-tools/metaharness-tools.js +1 -1
- package/dist/src/mcp-tools/neural-tools.js +20 -50
- package/dist/src/mcp-tools/policy-tools.js +5 -3
- package/dist/src/memory/intelligence.js +80 -33
- package/dist/src/memory/stats-file-lock.d.ts +7 -0
- package/dist/src/memory/stats-file-lock.js +53 -0
- package/dist/src/missions/schemas.d.ts +113 -113
- package/dist/src/mods/command-registry/schema.d.ts +193 -193
- package/dist/src/services/distill-oracle.d.ts +1 -1
- package/dist/src/services/distill-oracle.js +2 -2
- package/dist/src/services/policy-anchor-log.d.ts +13 -0
- package/dist/src/services/policy-anchor-log.js +242 -0
- package/dist/src/services/policy-archive-scan.d.ts +7 -0
- package/dist/src/services/policy-archive-scan.js +50 -0
- package/dist/src/services/policy-ledger-anchor.d.ts +14 -8
- package/dist/src/services/policy-ledger-anchor.js +356 -40
- package/dist/src/services/policy-ledger-audit.d.ts +22 -0
- package/dist/src/services/policy-ledger-audit.js +260 -0
- package/dist/src/services/policy-ledger-record.d.ts +3 -0
- package/dist/src/services/policy-ledger-record.js +22 -0
- package/dist/src/services/policy-runtime.d.ts +1 -0
- package/dist/src/services/policy-runtime.js +261 -40
- package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
- package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
- package/node_modules/@claude-flow/security/dist/input-validator.d.ts +6 -6
- package/node_modules/@claude-flow/security/dist/policy/engine.d.ts +17 -1
- package/node_modules/@claude-flow/security/dist/policy/engine.d.ts.map +1 -1
- package/node_modules/@claude-flow/security/dist/policy/engine.js +99 -24
- package/node_modules/@claude-flow/security/dist/policy/engine.js.map +1 -1
- package/node_modules/@claude-flow/security/dist/policy/types.d.ts +14 -1
- package/node_modules/@claude-flow/security/dist/policy/types.d.ts.map +1 -1
- package/node_modules/@claude-flow/security/dist/policy/types.js +3 -1
- package/node_modules/@claude-flow/security/dist/policy/types.js.map +1 -1
- package/package.json +3 -3
- package/plugins/ruflo-console/dist/tui.mjs +153 -153
- package/plugins/ruflo-metaharness/hooks/screen.ts +7 -1
- package/plugins/ruflo-metaharness/scripts/_darwin.mjs +4 -4
- package/plugins/ruflo-metaharness/.claude-flow/daemon-state.json +0 -179
- package/plugins/ruflo-metaharness/.claude-flow/daemon.pid +0 -1
- package/plugins/ruflo-metaharness/.claude-flow/logs/daemon.log +0 -32
- package/plugins/ruflo-metaharness/.claude-flow/metrics/backup.json +0 -23
- package/plugins/ruflo-metaharness/.claude-flow/metrics/codebase-map.json +0 -11
- package/plugins/ruflo-metaharness/.claude-flow/metrics/consolidation.json +0 -16
- package/plugins/ruflo-metaharness/.claude-flow/metrics/harness-loop.json +0 -91
- package/plugins/ruflo-metaharness/.claude-flow/metrics/performance.json +0 -17
- package/plugins/ruflo-metaharness/.claude-flow/metrics/security-audit.json +0 -12
- package/plugins/ruflo-metaharness/.claude-flow/metrics/test-gaps.json +0 -8
- package/plugins/ruflo-metaharness/.claude-flow/neural/patterns.json +0 -2809
- package/plugins/ruflo-metaharness/.claude-flow/neural/stats.json +0 -6
- package/plugins/ruflo-metaharness/.claude-flow/policy/state.json +0 -11
- package/plugins/ruflo-metaharness/.swarm/agentdb-memory.db +0 -0
- package/plugins/ruflo-metaharness/.swarm/agentdb-memory.db-shm +0 -0
- package/plugins/ruflo-metaharness/.swarm/agentdb-memory.db-wal +0 -0
- package/plugins/ruflo-metaharness/.swarm/backups/memory-2026-10-14T16-09-38-164Z.db +0 -0
- package/plugins/ruflo-metaharness/.swarm/backups/store-agentdb-memory.db-2026-10-14T16-09-38-166Z.db +0 -0
- package/plugins/ruflo-metaharness/.swarm/ewc-fisher.json +0 -397
- package/plugins/ruflo-metaharness/.swarm/memory.db +0 -0
- package/plugins/ruflo-metaharness/.swarm/memory.db-shm +0 -0
- package/plugins/ruflo-metaharness/.swarm/memory.db-wal +0 -0
- package/plugins/ruflo-metaharness/agentdb.rvf +0 -0
- package/plugins/ruflo-metaharness/agentdb.rvf.lock +0 -0
- package/plugins/ruflo-metaharness/ruvector.db +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.57.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.57.1",
|
|
4
4
|
"files": {
|
|
5
5
|
"auto-memory-hook.mjs": "631fac9d518835e2852a406888316bbbddddb49e7ed8e406d2e971f46833df9a",
|
|
6
6
|
"hook-handler.cjs": "bc12b3cae92d5a7c8deef699fa00d0ef07b57625c18dbeac4387f15725b8e09f",
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
"router.cjs": "16648b3c0d73b6681ac2d8d13def6a68286c57f5a11004de5b19a0fa088c833d"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
"signature": "
|
|
12
|
+
"signature": "4QJCbq039ufiBQ0tz2aVw1refajyDbptNNS+xaHszCNADeMKOzqL3pT3dh4k+hZgMn+zKYh1V0FOmF9GyXJhAA==",
|
|
13
13
|
"algorithm": "ed25519"
|
|
14
14
|
}
|
package/README.md
CHANGED
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
[](https://github.com/ruvnet/claude-flow)
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
|
-
<a href="
|
|
13
|
+
<a href="docs/harness-origins.md"><img src="https://raw.githubusercontent.com/ruvnet/ruflo/e69e4b95aa08d65ea0f7715489bbf8e62a83a0d2/docs/assets/readme/badges/first-commit.svg" width="300" height="76" alt="Claude Flow lineage: first commit June 2, 2025 by rUv; inspect the evidence"></a>
|
|
14
|
+
<a href="data/npm-downloads.latest.json"><img src="https://raw.githubusercontent.com/ruvnet/ruflo/275aff65a198af758923669acff36f03d1f41623/docs/assets/readme/badges/downloads.svg" width="300" height="76" alt="Illustrative download counter starts at 98,000,000 and adds varied amounts each second in a 30 second loop. Verified dataset: 97,022,120 download events."></a>
|
|
14
15
|
<br>
|
|
15
|
-
<a href="https://github.com/ruvnet/claude-flow"><img src="docs/assets/readme/badges/claude.svg
|
|
16
|
-
<a href="https://www.npmjs.com/package/@claude-flow/codex"><img src="docs/assets/readme/badges/codex.svg
|
|
16
|
+
<a href="https://github.com/ruvnet/claude-flow"><img src="https://raw.githubusercontent.com/ruvnet/ruflo/d1e80400bdefe01d3b13e70395f88fffab76bb18/docs/assets/readme/badges/claude.svg" width="300" height="76" alt="Claude Code plugin"></a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/@claude-flow/codex"><img src="https://raw.githubusercontent.com/ruvnet/ruflo/d1e80400bdefe01d3b13e70395f88fffab76bb18/docs/assets/readme/badges/codex.svg" width="300" height="76" alt="Codex plugin"></a>
|
|
17
18
|
</p>
|
|
18
19
|
|
|
19
20
|
</div>
|
|
@@ -109,6 +110,14 @@ User → Ruflo (CLI/MCP) → Router → Swarm → Agents → Memory → LLM prov
|
|
|
109
110
|
|
|
110
111
|
> **New to Ruflo?** You don't need to learn 314 MCP tools or 26 CLI commands. After `init`, just use Claude Code normally — the hooks system automatically routes tasks, learns from successful patterns, and coordinates agents in the background.
|
|
111
112
|
|
|
113
|
+
### An origin you can inspect
|
|
114
|
+
|
|
115
|
+
[](docs/harness-origins.md)
|
|
116
|
+
|
|
117
|
+
**Built by [Reuven Cohen (rUv)](https://github.com/ruvnet), originally as Claude Flow.** The [first commit, June 2, 2025](https://github.com/ruvnet/ruflo/commit/7c1f9402d70e7af56c01a879073cbac92564dc4e), describes a code orchestration layer for recursive agent cycles: Claude writes, edits, tests and improves. The [June 10 source snapshot](https://github.com/ruvnet/ruflo/tree/dba545f012ea92a2375a26332bbf3797495e93c9) adds orchestration, task scheduling, memory and terminal modules.
|
|
118
|
+
|
|
119
|
+
A harness is the workbench around the model: it organizes tasks, carries context between steps and helps check results. **This establishes Ruflo's lineage, not a universal first across every Claude Code tool.** [See the illustrated explainer, exact commits and earlier ecosystem context](docs/harness-origins.md).
|
|
120
|
+
|
|
112
121
|
<details>
|
|
113
122
|
<summary><strong>📖 Background — where the name comes from</strong></summary>
|
|
114
123
|
|
package/catalog-manifest.json
CHANGED
|
@@ -1247,12 +1247,18 @@ const statusCommand = {
|
|
|
1247
1247
|
// its real consent state into daemon-state.json — prefer that when it
|
|
1248
1248
|
// is the one running.
|
|
1249
1249
|
let aiWorkersEnabled = status.config.aiWorkersEnabled;
|
|
1250
|
+
// #4238: same for the TTL — a daemon started with `--ttl 0` must not be
|
|
1251
|
+
// reported with this process's 12h default.
|
|
1252
|
+
let ttlMs = status.config.ttlMs;
|
|
1250
1253
|
if (bgRunning) {
|
|
1251
1254
|
try {
|
|
1252
1255
|
const st = JSON.parse(fs.readFileSync(join(projectRoot, '.claude-flow', 'daemon-state.json'), 'utf-8'));
|
|
1253
1256
|
if (typeof st?.config?.aiWorkersEnabled === 'boolean') {
|
|
1254
1257
|
aiWorkersEnabled = st.config.aiWorkersEnabled;
|
|
1255
1258
|
}
|
|
1259
|
+
if (typeof st?.config?.ttlMs === 'number' && Number.isFinite(st.config.ttlMs)) {
|
|
1260
|
+
ttlMs = st.config.ttlMs;
|
|
1261
|
+
}
|
|
1256
1262
|
}
|
|
1257
1263
|
catch { /* no/partial state — fall back to in-process config */ }
|
|
1258
1264
|
}
|
|
@@ -1265,8 +1271,8 @@ const statusCommand = {
|
|
|
1265
1271
|
`Status: ${statusIcon} ${statusText}${mode}`,
|
|
1266
1272
|
`PID: ${displayPid}`,
|
|
1267
1273
|
status.startedAt ? `Started: ${status.startedAt.toISOString()}` : '',
|
|
1268
|
-
|
|
1269
|
-
? `TTL: ${Math.round(
|
|
1274
|
+
ttlMs > 0
|
|
1275
|
+
? `TTL: ${Math.round(ttlMs / 3600000)}h (self-shutdown)`
|
|
1270
1276
|
: `TTL: ${output.dim('off (runs until stopped)')}`,
|
|
1271
1277
|
// #2661: surface the AI-consent gate so "why is audit local-only?"
|
|
1272
1278
|
// is answerable from `daemon status` alone.
|
|
@@ -2515,6 +2515,12 @@ export const doctorCommand = {
|
|
|
2515
2515
|
name: 'doctor',
|
|
2516
2516
|
description: 'System diagnostics and health checks',
|
|
2517
2517
|
options: [
|
|
2518
|
+
{
|
|
2519
|
+
name: 'json',
|
|
2520
|
+
description: 'Emit versioned JSON health checks (cannot be combined with repair flags)',
|
|
2521
|
+
type: 'boolean',
|
|
2522
|
+
default: false
|
|
2523
|
+
},
|
|
2518
2524
|
{
|
|
2519
2525
|
name: 'fix',
|
|
2520
2526
|
short: 'f',
|
|
@@ -2561,6 +2567,7 @@ export const doctorCommand = {
|
|
|
2561
2567
|
}
|
|
2562
2568
|
],
|
|
2563
2569
|
examples: [
|
|
2570
|
+
{ command: 'claude-flow doctor --json -c node', description: 'Emit machine-readable health checks' },
|
|
2564
2571
|
{ command: 'claude-flow doctor', description: 'Run full health check' },
|
|
2565
2572
|
{ command: 'claude-flow doctor --fix', description: 'Print suggested fix commands (does not auto-apply)' },
|
|
2566
2573
|
{ command: 'claude-flow doctor --install', description: 'Auto-install missing dependencies' },
|
|
@@ -2575,6 +2582,21 @@ export const doctorCommand = {
|
|
|
2575
2582
|
const verbose = ctx.flags.verbose;
|
|
2576
2583
|
// Parser camelCases kebab-case flag names — read via `fixHandles`, not `['fix-handles']`.
|
|
2577
2584
|
const fixHandles = ctx.flags.fixHandles;
|
|
2585
|
+
const json = ctx.flags.json;
|
|
2586
|
+
const reportError = (message) => {
|
|
2587
|
+
if (json)
|
|
2588
|
+
output.writeln(JSON.stringify({ schemaVersion: 1, checks: [], error: message }));
|
|
2589
|
+
else
|
|
2590
|
+
output.printError(message);
|
|
2591
|
+
return { success: false, exitCode: 1, message };
|
|
2592
|
+
};
|
|
2593
|
+
if (json && (showFix || autoInstall || fixHandles)) {
|
|
2594
|
+
return reportError('--json cannot be combined with --fix, --install, or --fix-handles');
|
|
2595
|
+
}
|
|
2596
|
+
// Reuse the same callable for anonymous checks so their IDs do not depend
|
|
2597
|
+
// on display names or on whether the full or component suite was selected.
|
|
2598
|
+
const helperCheck = () => checkHelperIntegrity();
|
|
2599
|
+
const nativeAddonCheck = () => checkNativeAddonHeaders();
|
|
2578
2600
|
// #2677: `--component memory` now runs the whole memory-health suite,
|
|
2579
2601
|
// not just the existence check. Values can be a single check or an
|
|
2580
2602
|
// array — expanded at execution time. Stuinfla's report showed the
|
|
@@ -2592,7 +2614,7 @@ export const doctorCommand = {
|
|
|
2592
2614
|
'browser': checkAgentBrowserVersion,
|
|
2593
2615
|
'config': checkConfigFile,
|
|
2594
2616
|
'stale-settings': checkStaleSettingsNpx, // #2448
|
|
2595
|
-
'helpers':
|
|
2617
|
+
'helpers': helperCheck, // #3565
|
|
2596
2618
|
'daemon': checkDaemonStatus,
|
|
2597
2619
|
get memory() {
|
|
2598
2620
|
return [
|
|
@@ -2608,7 +2630,7 @@ export const doctorCommand = {
|
|
|
2608
2630
|
];
|
|
2609
2631
|
},
|
|
2610
2632
|
'memory-package': checkMemoryPackageVersion, // #3392
|
|
2611
|
-
'native-addon':
|
|
2633
|
+
'native-addon': nativeAddonCheck, // #4055
|
|
2612
2634
|
'learning': checkLearningBridge, // #2545
|
|
2613
2635
|
'learning-bridge': checkLearningBridge, // #2545
|
|
2614
2636
|
'api': checkApiKeys,
|
|
@@ -2634,8 +2656,7 @@ export const doctorCommand = {
|
|
|
2634
2656
|
};
|
|
2635
2657
|
if (component !== undefined && !Object.hasOwn(componentMap, component)) {
|
|
2636
2658
|
const message = `Unknown doctor component: ${JSON.stringify(component)}. Valid components: ${Object.keys(componentMap).join(', ')}`;
|
|
2637
|
-
|
|
2638
|
-
return { success: false, exitCode: 1, message };
|
|
2659
|
+
return reportError(message);
|
|
2639
2660
|
}
|
|
2640
2661
|
// Early-return short-circuit: `--fix-handles` is a targeted mitigation, not
|
|
2641
2662
|
// part of the health-check flow. Runs, reports, exits.
|
|
@@ -2699,12 +2720,15 @@ export const doctorCommand = {
|
|
|
2699
2720
|
output.writeln(output.dim('Upstream tracking: https://github.com/anthropics/claude-code/issues/67888'));
|
|
2700
2721
|
return { success: true };
|
|
2701
2722
|
}
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2723
|
+
if (!json) {
|
|
2724
|
+
output.writeln();
|
|
2725
|
+
output.writeln(output.bold('RuFlo Doctor'));
|
|
2726
|
+
output.writeln(output.dim('System diagnostics and health check'));
|
|
2727
|
+
output.writeln(output.dim('─'.repeat(50)));
|
|
2728
|
+
output.writeln();
|
|
2729
|
+
}
|
|
2730
|
+
const nativeAgentDbPaths = await existingNativeAgentDbPaths();
|
|
2731
|
+
const nativeAgentDbChecks = nativeAgentDbPaths
|
|
2708
2732
|
.map((dbPath) => () => checkNativeAgentDbStructuralIntegrity(dbPath));
|
|
2709
2733
|
const allChecks = [
|
|
2710
2734
|
checkVersionFreshness,
|
|
@@ -2716,7 +2740,7 @@ export const doctorCommand = {
|
|
|
2716
2740
|
checkGitRepo,
|
|
2717
2741
|
checkConfigFile,
|
|
2718
2742
|
checkStaleSettingsNpx, // #2448/#2677 — runaway `npx @latest` in settings
|
|
2719
|
-
|
|
2743
|
+
helperCheck, // #3565 — installed signed helpers vs manifest
|
|
2720
2744
|
checkDaemonStatus,
|
|
2721
2745
|
checkMemoryDatabase,
|
|
2722
2746
|
checkMemoryStructuralIntegrity, // #2737 — bounded, native quick_check on every default run
|
|
@@ -2724,7 +2748,7 @@ export const doctorCommand = {
|
|
|
2724
2748
|
checkMemoryPersistenceDriver, // #2968/#3321 — read-only native capability probe
|
|
2725
2749
|
checkLearningBridge, // #2545 — can the auto-memory hook actually load @claude-flow/memory?
|
|
2726
2750
|
checkMemoryPackageVersion, // #3392 — loaded @claude-flow/memory must satisfy the CLI's declared range
|
|
2727
|
-
|
|
2751
|
+
nativeAddonCheck, // #4055 — better-sqlite3 built against Node 24.19+ headers on 24.19-24.21
|
|
2728
2752
|
checkApiKeys,
|
|
2729
2753
|
checkMcpServers,
|
|
2730
2754
|
checkMcpSchemaOverhead, // #2726 — fixed tools/list prompt cost
|
|
@@ -2747,21 +2771,59 @@ export const doctorCommand = {
|
|
|
2747
2771
|
const entry = componentMap[component];
|
|
2748
2772
|
checksToRun = Array.isArray(entry) ? entry : [entry];
|
|
2749
2773
|
}
|
|
2774
|
+
// These are API identifiers: keep them stable even when user-facing names
|
|
2775
|
+
// change. Grouped components have a distinct ID for each individual check.
|
|
2776
|
+
const checkIds = new Map([
|
|
2777
|
+
[checkVersionFreshness, 'version'], [checkNodeVersion, 'node'],
|
|
2778
|
+
[checkNpmVersion, 'npm'], [checkClaudeCode, 'claude'],
|
|
2779
|
+
[checkAgentBrowserVersion, 'browser'], [checkGit, 'git'],
|
|
2780
|
+
[checkGitRepo, 'git-repo'], [checkConfigFile, 'config'],
|
|
2781
|
+
[checkStaleSettingsNpx, 'stale-settings'], [helperCheck, 'helpers'],
|
|
2782
|
+
[checkDaemonStatus, 'daemon'], [checkMemoryDatabase, 'memory-presence'],
|
|
2783
|
+
[checkMemoryStructuralIntegrity, 'memory-structural'],
|
|
2784
|
+
[checkMemoryIntegrity, 'memory-integrity'],
|
|
2785
|
+
[checkMemoryPersistenceDriver, 'memory-driver'],
|
|
2786
|
+
[checkMemoryPackageVersion, 'memory-package'],
|
|
2787
|
+
[checkMemoryContent, 'memory-content'],
|
|
2788
|
+
[checkMemoryEmbeddingCoverage, 'memory-embeddings'],
|
|
2789
|
+
[checkMemoryReflexionCoverage, 'memory-reflexion'],
|
|
2790
|
+
[checkMemoryCritiqueCoverage, 'memory-critique'],
|
|
2791
|
+
[checkLearningBridge, 'learning'], [nativeAddonCheck, 'native-addon'],
|
|
2792
|
+
[checkApiKeys, 'api'], [checkMcpServers, 'mcp'],
|
|
2793
|
+
[checkMcpSchemaOverhead, 'mcp-overhead'], [checkAIDefence, 'aidefence'],
|
|
2794
|
+
[checkDiskSpace, 'disk'], [checkBuildTools, 'typescript'],
|
|
2795
|
+
[checkAgenticFlow, 'agentic-flow'], [checkEncryptionAtRest, 'encryption'],
|
|
2796
|
+
[checkFederationBreaker, 'federation'], [checkMetaharness, 'metaharness'],
|
|
2797
|
+
[checkMetaharnessDeclaredPackages, 'metaharness-packages'],
|
|
2798
|
+
[checkMetaharnessIntegration, 'metaharness-integration'],
|
|
2799
|
+
[checkFunnel, 'funnel'], [checkProxySponsoredConsent, 'proxy-consent'],
|
|
2800
|
+
[checkProxyBinary, 'proxy-binary'], [checkProxyProcess, 'proxy-process'],
|
|
2801
|
+
[checkProxyBindAddress, 'proxy-bind'], [checkAuth, 'auth'],
|
|
2802
|
+
[checkTypesafeRouter, 'typesafe'], [checkMods, 'mods'],
|
|
2803
|
+
]);
|
|
2804
|
+
nativeAgentDbChecks.forEach((check, index) => {
|
|
2805
|
+
// The path distinguishes simultaneous authority files; normalize separators.
|
|
2806
|
+
checkIds.set(check, `memory-native:${nativeAgentDbPaths[index].replace(/\\/g, '/')}`);
|
|
2807
|
+
});
|
|
2808
|
+
if (json && checksToRun.some(check => !checkIds.has(check))) {
|
|
2809
|
+
return reportError('Doctor check is missing a stable JSON ID');
|
|
2810
|
+
}
|
|
2750
2811
|
const results = [];
|
|
2751
2812
|
const fixes = [];
|
|
2752
2813
|
// OPTIMIZATION: Run all checks in parallel for 3-5x faster execution
|
|
2753
|
-
const spinner = output.createSpinner({ text: 'Running health checks in parallel...', spinner: 'dots' });
|
|
2754
|
-
spinner
|
|
2814
|
+
const spinner = json ? undefined : output.createSpinner({ text: 'Running health checks in parallel...', spinner: 'dots' });
|
|
2815
|
+
spinner?.start();
|
|
2755
2816
|
try {
|
|
2756
2817
|
// Execute all checks concurrently
|
|
2757
2818
|
const checkResults = await Promise.allSettled(checksToRun.map(check => check()));
|
|
2758
|
-
spinner
|
|
2819
|
+
spinner?.stop();
|
|
2759
2820
|
// Process results in order
|
|
2760
2821
|
for (const settledResult of checkResults) {
|
|
2761
2822
|
if (settledResult.status === 'fulfilled') {
|
|
2762
2823
|
const result = settledResult.value;
|
|
2763
2824
|
results.push(result);
|
|
2764
|
-
|
|
2825
|
+
if (!json)
|
|
2826
|
+
output.writeln(formatCheck(result));
|
|
2765
2827
|
if (result.fix && (result.status === 'fail' || result.status === 'warn')) {
|
|
2766
2828
|
fixes.push(`${result.name}: ${result.fix}`);
|
|
2767
2829
|
}
|
|
@@ -2773,12 +2835,15 @@ export const doctorCommand = {
|
|
|
2773
2835
|
message: settledResult.reason?.message || 'Unknown error'
|
|
2774
2836
|
};
|
|
2775
2837
|
results.push(errorResult);
|
|
2776
|
-
|
|
2838
|
+
if (!json)
|
|
2839
|
+
output.writeln(formatCheck(errorResult));
|
|
2777
2840
|
}
|
|
2778
2841
|
}
|
|
2779
2842
|
}
|
|
2780
2843
|
catch (error) {
|
|
2781
|
-
spinner
|
|
2844
|
+
spinner?.stop();
|
|
2845
|
+
if (json)
|
|
2846
|
+
return reportError(`Failed to run health checks: ${error instanceof Error ? error.message : String(error)}`);
|
|
2782
2847
|
output.writeln(output.error('Failed to run health checks'));
|
|
2783
2848
|
}
|
|
2784
2849
|
// #2545: --fix / --install can actually repair the Learning Bridge by
|
|
@@ -2827,6 +2892,18 @@ export const doctorCommand = {
|
|
|
2827
2892
|
const passed = results.filter(r => r.status === 'pass').length;
|
|
2828
2893
|
const warnings = results.filter(r => r.status === 'warn').length;
|
|
2829
2894
|
const failed = results.filter(r => r.status === 'fail').length;
|
|
2895
|
+
if (json) {
|
|
2896
|
+
const checks = results.map((result, index) => ({
|
|
2897
|
+
id: checkIds.get(checksToRun[index]),
|
|
2898
|
+
status: result.status,
|
|
2899
|
+
name: result.name,
|
|
2900
|
+
detail: result.message,
|
|
2901
|
+
...(result.fix ? { fix: result.fix } : {}),
|
|
2902
|
+
}));
|
|
2903
|
+
const data = { schemaVersion: 1, checks };
|
|
2904
|
+
output.writeln(JSON.stringify(data));
|
|
2905
|
+
return { success: failed === 0, exitCode: failed > 0 ? 1 : 0, data };
|
|
2906
|
+
}
|
|
2830
2907
|
output.writeln();
|
|
2831
2908
|
output.writeln(output.dim('─'.repeat(50)));
|
|
2832
2909
|
output.writeln();
|
|
@@ -30,6 +30,7 @@ export const policyCommand = {
|
|
|
30
30
|
{ name: 'mode', type: 'string', description: 'Policy mode: legacy | observe | enforce' },
|
|
31
31
|
{ name: 'project-root', type: 'string', description: 'Project root containing .claude-flow/policy' },
|
|
32
32
|
{ name: 'establish-anchor', type: 'boolean', description: 'verify: explicitly anchor a ledger that has receipts but no anchor (interactive, logged with user and time)' },
|
|
33
|
+
{ name: 'full', type: 'boolean', description: 'verify: additionally replay the archived receipts (receipts.ledger.jsonl) to verify the complete historical chain, not just the retained hot tail' },
|
|
33
34
|
],
|
|
34
35
|
async action(context) {
|
|
35
36
|
const args = context.args ?? [];
|
|
@@ -93,9 +94,13 @@ export const policyCommand = {
|
|
|
93
94
|
}
|
|
94
95
|
if (operation === 'verify') {
|
|
95
96
|
const establishAnchor = flags['establish-anchor'] === true || flags.establishAnchor === true;
|
|
97
|
+
const full = flags.full === true;
|
|
96
98
|
if (establishAnchor)
|
|
97
99
|
requireInteractiveAdministrator();
|
|
98
|
-
const ledger = await verifyPolicyLedger(root, { establishAnchor });
|
|
100
|
+
const ledger = await verifyPolicyLedger(root, { establishAnchor, full });
|
|
101
|
+
if (ledger.error === 'receipt-key-id-mismatch') {
|
|
102
|
+
output.printError('Restore the original CLAUDE_FLOW_POLICY_KEY_ID for this ledger; do not rewrite or re-sign historical receipts.');
|
|
103
|
+
}
|
|
99
104
|
const result = print({ ...ledger, anchors: anchorPosture(root), scope: LEDGER_TRUST_SCOPE });
|
|
100
105
|
return ledger.valid ? result : { ...result, success: false, exitCode: 1 };
|
|
101
106
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -92,13 +92,13 @@ export class CLI {
|
|
|
92
92
|
const parseResult = this.parser.parse(args);
|
|
93
93
|
const { command: commandPath, flags, positional } = parseResult;
|
|
94
94
|
// Handle global flags
|
|
95
|
+
if (flags.noColor || flags.color === false) {
|
|
96
|
+
this.output.setColorEnabled(false);
|
|
97
|
+
}
|
|
95
98
|
if (flags.version || flags.V) {
|
|
96
99
|
this.showVersion();
|
|
97
100
|
return;
|
|
98
101
|
}
|
|
99
|
-
if (flags.noColor) {
|
|
100
|
-
this.output.setColorEnabled(false);
|
|
101
|
-
}
|
|
102
102
|
// Set verbosity level based on flags
|
|
103
103
|
if (flags.quiet) {
|
|
104
104
|
this.output.setVerbosity('quiet');
|
|
@@ -114,7 +114,7 @@ export class CLI {
|
|
|
114
114
|
this.output.printDebug(`CWD: ${process.cwd()}`);
|
|
115
115
|
}
|
|
116
116
|
// Run startup update check (non-blocking, silent on skip)
|
|
117
|
-
if (!flags.noUpdate && commandPath[0] !== 'update') {
|
|
117
|
+
if (!flags.noUpdate && flags.update !== false && commandPath[0] !== 'update' && !(commandPath[0] === 'doctor' && flags.json)) {
|
|
118
118
|
this.checkForUpdatesOnStartup().catch(() => { });
|
|
119
119
|
}
|
|
120
120
|
// Version-stamped helper auto-refresh — propagate hook fixes to an already
|
|
@@ -536,7 +536,7 @@ export class CLI {
|
|
|
536
536
|
catch (error) {
|
|
537
537
|
// Config loading is optional - don't fail if it doesn't exist
|
|
538
538
|
if (process.env.DEBUG) {
|
|
539
|
-
this.output.
|
|
539
|
+
this.output.writeErrorln(this.output.dim(`Config loading failed: ${error.message}`));
|
|
540
540
|
}
|
|
541
541
|
return undefined;
|
|
542
542
|
}
|
|
@@ -27,7 +27,6 @@ export function generateSettings(options) {
|
|
|
27
27
|
allow: [
|
|
28
28
|
'Bash(npx @claude-flow*)',
|
|
29
29
|
'Bash(npx claude-flow*)',
|
|
30
|
-
'Bash(node .claude/*)',
|
|
31
30
|
'mcp__claude-flow__*',
|
|
32
31
|
],
|
|
33
32
|
deny: [
|
|
@@ -201,7 +200,7 @@ function generateHooksConfig(config, scope) {
|
|
|
201
200
|
const hooks = {};
|
|
202
201
|
// Node.js scripts handle errors internally via try/catch.
|
|
203
202
|
// No shell-level error suppression needed (2>/dev/null || true breaks Windows).
|
|
204
|
-
// PreToolUse — validate commands
|
|
203
|
+
// PreToolUse — validate shell commands before execution
|
|
205
204
|
if (config.preToolUse) {
|
|
206
205
|
hooks.PreToolUse = [
|
|
207
206
|
{
|
|
@@ -214,19 +213,9 @@ function generateHooksConfig(config, scope) {
|
|
|
214
213
|
},
|
|
215
214
|
],
|
|
216
215
|
},
|
|
217
|
-
{
|
|
218
|
-
matcher: 'Write|Edit|MultiEdit',
|
|
219
|
-
hooks: [
|
|
220
|
-
{
|
|
221
|
-
type: 'command',
|
|
222
|
-
command: hookHandlerCmd('pre-edit', scope),
|
|
223
|
-
timeout: config.timeout,
|
|
224
|
-
},
|
|
225
|
-
],
|
|
226
|
-
},
|
|
227
216
|
];
|
|
228
217
|
}
|
|
229
|
-
// PostToolUse — record edits
|
|
218
|
+
// PostToolUse — record edits for session metrics / learning
|
|
230
219
|
if (config.postToolUse) {
|
|
231
220
|
hooks.PostToolUse = [
|
|
232
221
|
{
|
|
@@ -239,16 +228,6 @@ function generateHooksConfig(config, scope) {
|
|
|
239
228
|
},
|
|
240
229
|
],
|
|
241
230
|
},
|
|
242
|
-
{
|
|
243
|
-
matcher: 'Bash',
|
|
244
|
-
hooks: [
|
|
245
|
-
{
|
|
246
|
-
type: 'command',
|
|
247
|
-
command: hookHandlerCmd('post-bash', scope),
|
|
248
|
-
timeout: config.timeout,
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
},
|
|
252
231
|
];
|
|
253
232
|
}
|
|
254
233
|
// UserPromptSubmit — intelligent task routing
|
|
@@ -312,16 +291,13 @@ function generateHooksConfig(config, scope) {
|
|
|
312
291
|
},
|
|
313
292
|
];
|
|
314
293
|
}
|
|
315
|
-
// PreCompact —
|
|
294
|
+
// PreCompact — end the current session before compaction. The handler has no
|
|
295
|
+
// manual/automatic compaction-specific command, so don't wire no-op hooks.
|
|
316
296
|
if (config.preCompact) {
|
|
317
297
|
hooks.PreCompact = [
|
|
318
298
|
{
|
|
319
299
|
matcher: 'manual',
|
|
320
300
|
hooks: [
|
|
321
|
-
{
|
|
322
|
-
type: 'command',
|
|
323
|
-
command: hookHandlerCmd('compact-manual', scope),
|
|
324
|
-
},
|
|
325
301
|
{
|
|
326
302
|
type: 'command',
|
|
327
303
|
command: hookHandlerCmd('session-end', scope),
|
|
@@ -332,10 +308,6 @@ function generateHooksConfig(config, scope) {
|
|
|
332
308
|
{
|
|
333
309
|
matcher: 'auto',
|
|
334
310
|
hooks: [
|
|
335
|
-
{
|
|
336
|
-
type: 'command',
|
|
337
|
-
command: hookHandlerCmd('compact-auto', scope),
|
|
338
|
-
},
|
|
339
311
|
{
|
|
340
312
|
type: 'command',
|
|
341
313
|
command: hookHandlerCmd('session-end', scope),
|
|
@@ -345,18 +317,6 @@ function generateHooksConfig(config, scope) {
|
|
|
345
317
|
},
|
|
346
318
|
];
|
|
347
319
|
}
|
|
348
|
-
// SubagentStart — status update when a sub-agent is spawned
|
|
349
|
-
hooks.SubagentStart = [
|
|
350
|
-
{
|
|
351
|
-
hooks: [
|
|
352
|
-
{
|
|
353
|
-
type: 'command',
|
|
354
|
-
command: hookHandlerCmd('status', scope),
|
|
355
|
-
timeout: 3000,
|
|
356
|
-
},
|
|
357
|
-
],
|
|
358
|
-
},
|
|
359
|
-
];
|
|
360
320
|
// SubagentStop — track agent completion for metrics
|
|
361
321
|
// NOTE: The valid event is "SubagentStop" (not "SubagentEnd")
|
|
362
322
|
hooks.SubagentStop = [
|
|
@@ -370,20 +330,6 @@ function generateHooksConfig(config, scope) {
|
|
|
370
330
|
],
|
|
371
331
|
},
|
|
372
332
|
];
|
|
373
|
-
// Notification — capture Claude Code notifications for logging
|
|
374
|
-
if (config.notification) {
|
|
375
|
-
hooks.Notification = [
|
|
376
|
-
{
|
|
377
|
-
hooks: [
|
|
378
|
-
{
|
|
379
|
-
type: 'command',
|
|
380
|
-
command: hookHandlerCmd('notify', scope),
|
|
381
|
-
timeout: 3000,
|
|
382
|
-
},
|
|
383
|
-
],
|
|
384
|
-
},
|
|
385
|
-
];
|
|
386
|
-
}
|
|
387
333
|
// NOTE: TeammateIdle, TaskCompleted, and PostCompact are NOT accepted by
|
|
388
334
|
// Claude Code's settings.json validator (rejected as "Invalid key in record").
|
|
389
335
|
// Agent Teams coordination lives in claudeFlow.agentTeams.hooks instead.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @module v3/cli/mcp-tools/memory-tools
|
|
11
11
|
*/
|
|
12
|
-
import type
|
|
12
|
+
import { type MCPTool } from './types.js';
|
|
13
13
|
export declare const DANGEROUS_KEY_PATTERN: RegExp;
|
|
14
14
|
/**
|
|
15
15
|
* #3570: the one key rule for every memory write path (MCP store, CLI store,
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from 'fs';
|
|
13
13
|
import { homedir } from 'os';
|
|
14
|
-
import { join, resolve } from 'path';
|
|
14
|
+
import { basename, dirname, join, resolve } from 'path';
|
|
15
|
+
import { execFileSync } from 'node:child_process';
|
|
15
16
|
import { createHash } from 'crypto';
|
|
17
|
+
import { getProjectCwd } from './types.js';
|
|
16
18
|
import { validateIdentifier } from './validate-input.js';
|
|
17
19
|
import { DEFAULT_SEARCH_THRESHOLD, nearMisses } from '../memory/search-defaults.js';
|
|
18
20
|
// #1604: Align with memory-initializer.ts — single source of truth is .swarm/memory.db
|
|
@@ -146,7 +148,24 @@ function resolveProjectMemoryDir(claudeProjectsDir, projectPathOverride) {
|
|
|
146
148
|
sources.push(projectPathOverride);
|
|
147
149
|
}
|
|
148
150
|
else {
|
|
149
|
-
|
|
151
|
+
const project = getProjectCwd();
|
|
152
|
+
sources.push(project);
|
|
153
|
+
// Claude Code shares auto-memory across linked Git worktrees under the
|
|
154
|
+
// main checkout's project slug. Preserve the direct-path match first,
|
|
155
|
+
// then try the common Git directory's parent. Explicit overrides above
|
|
156
|
+
// remain authoritative, and non-Git projects need no Git dependency.
|
|
157
|
+
try {
|
|
158
|
+
const commonDir = execFileSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], {
|
|
159
|
+
cwd: project,
|
|
160
|
+
encoding: 'utf-8',
|
|
161
|
+
timeout: 1000,
|
|
162
|
+
windowsHide: true,
|
|
163
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
164
|
+
}).trim();
|
|
165
|
+
if (basename(commonDir) === '.git')
|
|
166
|
+
sources.push(dirname(resolve(project, commonDir)));
|
|
167
|
+
}
|
|
168
|
+
catch { /* Git unavailable or not a repository: use the project path */ }
|
|
150
169
|
}
|
|
151
170
|
for (const source of sources) {
|
|
152
171
|
// Candidate 1: legacy POSIX hash — what shipped before #1883
|
|
@@ -1066,6 +1085,7 @@ export const memoryTools = [
|
|
|
1066
1085
|
}
|
|
1067
1086
|
let imported = 0;
|
|
1068
1087
|
let skipped = 0;
|
|
1088
|
+
const importErrors = [];
|
|
1069
1089
|
// #1791.8 — Claude Code's `~/.claude/projects/` accumulates historical
|
|
1070
1090
|
// project_id directories (truncated forms, sandbox cwds, renamed
|
|
1071
1091
|
// workspaces) that all contain copies of the same memory files. The
|
|
@@ -1105,7 +1125,7 @@ export const memoryTools = [
|
|
|
1105
1125
|
// #1884 — sanitize key so memory_delete can later remove it. Without
|
|
1106
1126
|
// this, dangerous chars from frontmatter `name` strand the key.
|
|
1107
1127
|
const key = sanitizeMemoryKey(`claude:${memFile.project}:${name}`);
|
|
1108
|
-
const stored = await storeEntry({ key, value: body, namespace: ns, generateEmbeddingFlag: true });
|
|
1128
|
+
const stored = await storeEntry({ key, value: body, namespace: ns, generateEmbeddingFlag: true, upsert: true });
|
|
1109
1129
|
if (!stored.success)
|
|
1110
1130
|
throw new Error(stored.error || `Failed to store ${key}`);
|
|
1111
1131
|
imported++;
|
|
@@ -1120,15 +1140,19 @@ export const memoryTools = [
|
|
|
1120
1140
|
// #1884 — sanitize so any dangerous chars in the heading don't
|
|
1121
1141
|
// produce keys memory_delete will reject.
|
|
1122
1142
|
const key = sanitizeMemoryKey(`claude:${memFile.project}:${name}:${sectionTitle.slice(0, 50)}`);
|
|
1123
|
-
const stored = await storeEntry({ key, value: sectionBody, namespace: ns, generateEmbeddingFlag: true });
|
|
1143
|
+
const stored = await storeEntry({ key, value: sectionBody, namespace: ns, generateEmbeddingFlag: true, upsert: true });
|
|
1124
1144
|
if (!stored.success)
|
|
1125
1145
|
throw new Error(stored.error || `Failed to store ${key}`);
|
|
1126
1146
|
imported++;
|
|
1127
1147
|
}
|
|
1128
1148
|
}
|
|
1129
1149
|
}
|
|
1130
|
-
catch {
|
|
1150
|
+
catch (err) {
|
|
1131
1151
|
skipped++;
|
|
1152
|
+
// Say why a file was skipped instead of returning a bare failure (#4197).
|
|
1153
|
+
if (importErrors.length < 5) {
|
|
1154
|
+
importErrors.push(`${memFile.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1155
|
+
}
|
|
1132
1156
|
}
|
|
1133
1157
|
}
|
|
1134
1158
|
// AUDIT #3: report the embedding backend truthfully — a hash-fallback
|
|
@@ -1147,6 +1171,7 @@ export const memoryTools = [
|
|
|
1147
1171
|
skipped,
|
|
1148
1172
|
duplicatesSkipped,
|
|
1149
1173
|
excludedByPattern,
|
|
1174
|
+
...(importErrors.length > 0 ? { errors: importErrors } : {}),
|
|
1150
1175
|
files: memoryFiles.length,
|
|
1151
1176
|
projects: projects.size,
|
|
1152
1177
|
namespace: ns,
|
|
@@ -399,7 +399,7 @@ export const metaharnessTools = [
|
|
|
399
399
|
},
|
|
400
400
|
// ───────────────────────────────────────────────────────────────────────
|
|
401
401
|
// ADR-153 — @metaharness/darwin integration (3 tools).
|
|
402
|
-
// Backed by the separate `@metaharness/darwin@~0.
|
|
402
|
+
// Backed by the separate `@metaharness/darwin@~0.12.0` npm package, NOT
|
|
403
403
|
// the umbrella `metaharness`. Plugin scripts shell out via _darwin.mjs.
|
|
404
404
|
// Same {success, data, degraded, exitCode} contract.
|
|
405
405
|
// ───────────────────────────────────────────────────────────────────────
|