claude-flow 3.57.0 → 3.57.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/intelligence.cjs +3 -5
- package/.claude/proven-config.json +1 -1
- package/README.md +12 -3
- package/node_modules/@claude-flow/codex/README.md +9 -9
- package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
- package/node_modules/@claude-flow/codex/dist/dual-mode/cli.js +3 -3
- package/node_modules/@claude-flow/codex/dist/dual-mode/cli.js.map +1 -1
- package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
- package/package.json +3 -2
- package/v3/@claude-flow/cli/README.md +12 -3
- package/v3/@claude-flow/cli/catalog-manifest.json +2 -2
- package/v3/@claude-flow/cli/dist/src/commands/hooks.js +20 -1
- package/v3/@claude-flow/cli/dist/src/commands/memory.js +25 -1
- package/v3/@claude-flow/cli/dist/src/commands/workflow.js +55 -15
- package/v3/@claude-flow/cli/dist/src/init/executor.js +9 -5
- package/v3/@claude-flow/cli/dist/src/init/helper-companions.d.ts +1 -1
- package/v3/@claude-flow/cli/dist/src/init/helper-companions.js +4 -3
- package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +9 -3
- package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +58 -9
- package/v3/@claude-flow/cli/dist/src/mcp-tools/workflow-tools.js +2 -1
- package/v3/@claude-flow/cli/dist/src/memory/graph-edge-writer.d.ts +16 -4
- package/v3/@claude-flow/cli/dist/src/memory/graph-edge-writer.js +19 -7
- package/v3/@claude-flow/cli/dist/src/memory/intelligence.js +4 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +12 -5
- package/v3/@claude-flow/cli/dist/src/missions/schemas.d.ts +113 -113
- package/v3/@claude-flow/cli/dist/src/mods/command-registry/schema.d.ts +193 -193
- package/v3/@claude-flow/cli/dist/src/services/memory-backup.d.ts +6 -0
- package/v3/@claude-flow/cli/dist/src/services/memory-backup.js +109 -81
- package/v3/@claude-flow/cli/dist/src/services/policy-ledger-anchor.d.ts +2 -0
- package/v3/@claude-flow/cli/dist/src/services/policy-ledger-anchor.js +4 -4
- package/v3/@claude-flow/cli/dist/src/services/policy-runtime.js +54 -3
- package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +4 -0
- package/v3/@claude-flow/cli/package.json +5 -4
|
@@ -227,15 +227,31 @@ function loadLegacyStore() {
|
|
|
227
227
|
/**
|
|
228
228
|
* Mark migration as complete
|
|
229
229
|
*/
|
|
230
|
-
function markMigrationComplete() {
|
|
230
|
+
function markMigrationComplete(counts) {
|
|
231
231
|
const legacyDir = resolve(LEGACY_MEMORY_DIR);
|
|
232
232
|
if (!existsSync(legacyDir))
|
|
233
233
|
mkdirSync(legacyDir, { recursive: true });
|
|
234
234
|
writeFileSync(resolve(join(LEGACY_MEMORY_DIR, MIGRATION_MARKER)), JSON.stringify({
|
|
235
235
|
migratedAt: new Date().toISOString(),
|
|
236
236
|
version: '3.0.0',
|
|
237
|
+
...(counts ?? {}),
|
|
237
238
|
}), 'utf-8');
|
|
238
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Counts recorded by the migration that wrote the marker, or null when no
|
|
242
|
+
* marker (or an older marker without counts) is present.
|
|
243
|
+
*/
|
|
244
|
+
function readMigrationCounts() {
|
|
245
|
+
try {
|
|
246
|
+
const marker = JSON.parse(readFileSync(resolve(join(LEGACY_MEMORY_DIR, MIGRATION_MARKER)), 'utf-8'));
|
|
247
|
+
return typeof marker?.migrated === 'number' && typeof marker?.total === 'number'
|
|
248
|
+
? { migrated: marker.migrated, total: marker.total }
|
|
249
|
+
: null;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
239
255
|
/**
|
|
240
256
|
* Lazy-load memory initializer functions to avoid circular deps
|
|
241
257
|
*/
|
|
@@ -391,7 +407,7 @@ async function ensureInitialized(dbPath) {
|
|
|
391
407
|
}
|
|
392
408
|
}
|
|
393
409
|
console.error(`[MCP Memory] Migrated ${migrated}/${Object.keys(legacyStore.entries).length} entries`);
|
|
394
|
-
markMigrationComplete();
|
|
410
|
+
markMigrationComplete({ migrated, total: Object.keys(legacyStore.entries).length });
|
|
395
411
|
}
|
|
396
412
|
}
|
|
397
413
|
}
|
|
@@ -636,7 +652,11 @@ export const memoryTools = [
|
|
|
636
652
|
});
|
|
637
653
|
return {
|
|
638
654
|
results: r.results.map(e => ({
|
|
639
|
-
|
|
655
|
+
// #2271: searchEntries() truncates ids to 12 chars ("entry_" +
|
|
656
|
+
// the leading digits of Date.now()), so entries written within
|
|
657
|
+
// ~2.8h share one id and RRF fused them into a single result.
|
|
658
|
+
// SmartRetrieval dedupes on id: give it the (namespace, key) tuple.
|
|
659
|
+
id: JSON.stringify([e.namespace, e.key]),
|
|
640
660
|
key: e.key,
|
|
641
661
|
content: e.content,
|
|
642
662
|
score: e.score,
|
|
@@ -966,11 +986,17 @@ export const memoryTools = [
|
|
|
966
986
|
},
|
|
967
987
|
handler: async (input) => {
|
|
968
988
|
const force = input.force;
|
|
969
|
-
// Remove migration marker if forcing
|
|
989
|
+
// Remove the migration marker if forcing. hasLegacyStore() checks the marker
|
|
990
|
+
// beside the legacy store, so that is the one force must clear (#4194);
|
|
991
|
+
// the old .swarm marker path is cleared too for compatibility.
|
|
970
992
|
if (force) {
|
|
971
|
-
const markerPath
|
|
972
|
-
|
|
973
|
-
|
|
993
|
+
for (const markerPath of [
|
|
994
|
+
resolve(join(LEGACY_MEMORY_DIR, MIGRATION_MARKER)),
|
|
995
|
+
getMigrationMarkerPath(),
|
|
996
|
+
]) {
|
|
997
|
+
if (existsSync(markerPath)) {
|
|
998
|
+
unlinkSync(markerPath);
|
|
999
|
+
}
|
|
974
1000
|
}
|
|
975
1001
|
}
|
|
976
1002
|
// Check for legacy data
|
|
@@ -982,12 +1008,35 @@ export const memoryTools = [
|
|
|
982
1008
|
migrated: 0,
|
|
983
1009
|
};
|
|
984
1010
|
}
|
|
1011
|
+
// A marker beside the store means a migration already ran; ensureInitialized
|
|
1012
|
+
// would move nothing, so say so instead of reporting the store's size.
|
|
1013
|
+
if (!hasLegacyStore()) {
|
|
1014
|
+
return {
|
|
1015
|
+
success: true,
|
|
1016
|
+
message: 'Legacy store already migrated (marker present); nothing was moved. Pass force: true to re-run.',
|
|
1017
|
+
migrated: 0,
|
|
1018
|
+
total: Object.keys(legacyStore.entries).length,
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
985
1021
|
// Run migration via ensureInitialized
|
|
986
1022
|
await ensureInitialized();
|
|
1023
|
+
// ensureInitialized swallows errors and records what it moved in the marker.
|
|
1024
|
+
const counts = readMigrationCounts();
|
|
1025
|
+
if (!counts) {
|
|
1026
|
+
return {
|
|
1027
|
+
success: false,
|
|
1028
|
+
message: 'Migration did not complete; no entries were recorded as migrated. See the MCP server log.',
|
|
1029
|
+
migrated: 0,
|
|
1030
|
+
total: Object.keys(legacyStore.entries).length,
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
987
1033
|
return {
|
|
988
1034
|
success: true,
|
|
989
|
-
message:
|
|
990
|
-
|
|
1035
|
+
message: counts.migrated === counts.total
|
|
1036
|
+
? 'Migration completed'
|
|
1037
|
+
: `Migration completed with failures: ${counts.migrated} of ${counts.total} entries migrated`,
|
|
1038
|
+
migrated: counts.migrated,
|
|
1039
|
+
total: counts.total,
|
|
991
1040
|
backend: await describeBackend(),
|
|
992
1041
|
};
|
|
993
1042
|
},
|
|
@@ -577,7 +577,8 @@ export const workflowTools = [
|
|
|
577
577
|
const store = loadWorkflowStore();
|
|
578
578
|
let workflows = Object.values(store.workflows);
|
|
579
579
|
// Apply filters
|
|
580
|
-
|
|
580
|
+
// 'all' is the CLI's explicit "no filter" value (`workflow list` sends it by default).
|
|
581
|
+
if (input.status && input.status !== 'all') {
|
|
581
582
|
workflows = workflows.filter(w => w.status === input.status);
|
|
582
583
|
}
|
|
583
584
|
// Sort by creation date (newest first)
|
|
@@ -30,10 +30,12 @@
|
|
|
30
30
|
* @module v3/cli/memory/graph-edge-writer
|
|
31
31
|
*/
|
|
32
32
|
/**
|
|
33
|
-
* True iff the memory.db bridge at `customDbPath`
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* True iff the memory.db bridge at `customDbPath` — or, when omitted, the
|
|
34
|
+
* path `resolveDbPath()` resolves from the `CLAUDE_FLOW_DB_PATH` env binding
|
|
35
|
+
* / memory root default (#4291) — is currently RFE1-encrypted-at-rest.
|
|
36
|
+
* Callers that receive `null` from getBridgeDb()/insertGraphEdge() can use
|
|
37
|
+
* this to avoid recommending the destructive `memory init` command for this
|
|
38
|
+
* specific, non-corrupt case.
|
|
37
39
|
*/
|
|
38
40
|
export declare function isBridgeDbEncryptedAtRest(customDbPath?: string): boolean;
|
|
39
41
|
/** Test-only: clear the once-per-path warning dedup set. */
|
|
@@ -60,6 +62,16 @@ export declare function releaseBridgeDb(dbPath?: string): boolean;
|
|
|
60
62
|
* #2431 fix: better-sqlite3 + WAL mode replaces sql.js + whole-file
|
|
61
63
|
* writeFileSync. Eliminates the dual-write race that corrupted memory.db
|
|
62
64
|
* when called alongside the memory bridge's better-sqlite3 writer.
|
|
65
|
+
*
|
|
66
|
+
* #4291 fix: the file is resolved via `resolveDbPath()` — the project's one
|
|
67
|
+
* documented path-priority rule (explicit `customDbPath` argument wins, then
|
|
68
|
+
* the `CLAUDE_FLOW_DB_PATH` env binding, then the plain `memory.db` default
|
|
69
|
+
* under the memory root) — instead of a local `customDbPath ?? <default>`
|
|
70
|
+
* expression that silently ignored `CLAUDE_FLOW_DB_PATH`. A caller that
|
|
71
|
+
* explicitly selected a store via that env var no longer gets answers read
|
|
72
|
+
* from a different, unselected database file. When the resolved file is
|
|
73
|
+
* missing (and `createIfMissing` is false) or encrypted at rest, this
|
|
74
|
+
* refuses (returns null) rather than falling back to any other store.
|
|
63
75
|
*/
|
|
64
76
|
export declare function getBridgeDb(customDbPath?: string, opts?: {
|
|
65
77
|
createIfMissing?: boolean;
|
|
@@ -33,7 +33,7 @@ import * as path from 'path';
|
|
|
33
33
|
import * as fs from 'fs';
|
|
34
34
|
import * as crypto from 'crypto';
|
|
35
35
|
import { execFileSync } from 'child_process';
|
|
36
|
-
import {
|
|
36
|
+
import { resolveDbPath } from './memory-initializer.js';
|
|
37
37
|
import { encodeEmbedding } from './embedding-quantization.js';
|
|
38
38
|
import { loadBetterSqlite3 } from './shared-sqlite.js';
|
|
39
39
|
import { isEncryptedBlob } from '../encryption/vault.js';
|
|
@@ -125,13 +125,15 @@ function warnRfe1EncryptedOnce(dbPath) {
|
|
|
125
125
|
'See #2889 (https://github.com/ruvnet/ruflo/issues/2889) for details and recovery options.');
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
|
-
* True iff the memory.db bridge at `customDbPath`
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
128
|
+
* True iff the memory.db bridge at `customDbPath` — or, when omitted, the
|
|
129
|
+
* path `resolveDbPath()` resolves from the `CLAUDE_FLOW_DB_PATH` env binding
|
|
130
|
+
* / memory root default (#4291) — is currently RFE1-encrypted-at-rest.
|
|
131
|
+
* Callers that receive `null` from getBridgeDb()/insertGraphEdge() can use
|
|
132
|
+
* this to avoid recommending the destructive `memory init` command for this
|
|
133
|
+
* specific, non-corrupt case.
|
|
132
134
|
*/
|
|
133
135
|
export function isBridgeDbEncryptedAtRest(customDbPath) {
|
|
134
|
-
const dbPath = customDbPath
|
|
136
|
+
const dbPath = resolveDbPath(customDbPath);
|
|
135
137
|
return fs.existsSync(dbPath) && isRfe1EncryptedAtRest(dbPath);
|
|
136
138
|
}
|
|
137
139
|
/** Test-only: clear the once-per-path warning dedup set. */
|
|
@@ -222,9 +224,19 @@ export function releaseBridgeDb(dbPath) {
|
|
|
222
224
|
* #2431 fix: better-sqlite3 + WAL mode replaces sql.js + whole-file
|
|
223
225
|
* writeFileSync. Eliminates the dual-write race that corrupted memory.db
|
|
224
226
|
* when called alongside the memory bridge's better-sqlite3 writer.
|
|
227
|
+
*
|
|
228
|
+
* #4291 fix: the file is resolved via `resolveDbPath()` — the project's one
|
|
229
|
+
* documented path-priority rule (explicit `customDbPath` argument wins, then
|
|
230
|
+
* the `CLAUDE_FLOW_DB_PATH` env binding, then the plain `memory.db` default
|
|
231
|
+
* under the memory root) — instead of a local `customDbPath ?? <default>`
|
|
232
|
+
* expression that silently ignored `CLAUDE_FLOW_DB_PATH`. A caller that
|
|
233
|
+
* explicitly selected a store via that env var no longer gets answers read
|
|
234
|
+
* from a different, unselected database file. When the resolved file is
|
|
235
|
+
* missing (and `createIfMissing` is false) or encrypted at rest, this
|
|
236
|
+
* refuses (returns null) rather than falling back to any other store.
|
|
225
237
|
*/
|
|
226
238
|
export async function getBridgeDb(customDbPath, opts) {
|
|
227
|
-
const dbPath = customDbPath
|
|
239
|
+
const dbPath = resolveDbPath(customDbPath);
|
|
228
240
|
const createIfMissing = opts?.createIfMissing === true;
|
|
229
241
|
if (_db && _dbPath === dbPath) {
|
|
230
242
|
armIdleRelease();
|
|
@@ -1077,6 +1077,10 @@ export async function recordTrajectory(steps, verdict) {
|
|
|
1077
1077
|
}
|
|
1078
1078
|
bumpStat('trajectoriesRecorded');
|
|
1079
1079
|
globalStats.lastAdaptation = Date.now();
|
|
1080
|
+
// #4283: the bank's own save is debounced, and the one-shot bins exit as
|
|
1081
|
+
// soon as the command resolves, so write the patterns now. Otherwise
|
|
1082
|
+
// stats.json counts patterns that never reach patterns.json.
|
|
1083
|
+
reasoningBank?.flushToDisk();
|
|
1080
1084
|
savePersistedStats();
|
|
1081
1085
|
return true;
|
|
1082
1086
|
}
|
|
@@ -2131,15 +2131,19 @@ async function loadLocalEmbeddingChain(verbose = false, startTime = Date.now())
|
|
|
2131
2131
|
if (verbose) {
|
|
2132
2132
|
console.log('Loading agentic-flow ReasoningBank embedding model...');
|
|
2133
2133
|
}
|
|
2134
|
+
// #3113: register a callable, like the ruvector branch below —
|
|
2135
|
+
// generateLocalEmbedding() only invokes function models. The bundled
|
|
2136
|
+
// model is all-MiniLM-L6-v2 (384-dim, per agentic-flow's
|
|
2137
|
+
// getEmbeddingDimensions()).
|
|
2134
2138
|
embeddingModelState = {
|
|
2135
2139
|
loaded: true,
|
|
2136
|
-
model:
|
|
2140
|
+
model: (text) => reasoningBank.computeEmbedding(text),
|
|
2137
2141
|
tokenizer: null,
|
|
2138
|
-
dimensions:
|
|
2142
|
+
dimensions: 384
|
|
2139
2143
|
};
|
|
2140
2144
|
return {
|
|
2141
2145
|
success: true,
|
|
2142
|
-
dimensions:
|
|
2146
|
+
dimensions: 384,
|
|
2143
2147
|
modelName: 'agentic-flow/reasoningbank',
|
|
2144
2148
|
loadTime: Date.now() - startTime
|
|
2145
2149
|
};
|
|
@@ -2272,10 +2276,13 @@ export async function generateLocalEmbedding(text) {
|
|
|
2272
2276
|
if (state.model && typeof state.model === 'function') {
|
|
2273
2277
|
try {
|
|
2274
2278
|
const output = await state.model(text, { pooling: 'mean', normalize: true });
|
|
2275
|
-
// Handle
|
|
2279
|
+
// Handle @xenova/transformers (output.data), ruvector (plain array) and
|
|
2280
|
+
// typed-array (ReasoningBank Float32Array, #3114) formats. DataView is an
|
|
2281
|
+
// ArrayBuffer view without an iterator (Array.from gives []), so exclude it.
|
|
2276
2282
|
const embedding = output?.data
|
|
2277
2283
|
? Array.from(output.data)
|
|
2278
|
-
: Array.isArray(output) ? output
|
|
2284
|
+
: Array.isArray(output) ? output
|
|
2285
|
+
: ArrayBuffer.isView(output) && !(output instanceof DataView) ? Array.from(output) : null;
|
|
2279
2286
|
if (embedding) {
|
|
2280
2287
|
return {
|
|
2281
2288
|
embedding,
|