@claude-flow/cli 3.56.9 → 3.57.0

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 (101) hide show
  1. package/.claude/helpers/.helpers-version +1 -1
  2. package/.claude/helpers/helpers.manifest.json +3 -3
  3. package/.claude/helpers/intelligence.cjs +51 -9
  4. package/.claude/helpers/router.cjs +0 -0
  5. package/.claude/skills/verification-quality/SKILL.md +14 -11
  6. package/README.md +1 -1
  7. package/catalog-manifest.json +2 -2
  8. package/dist/src/autopilot-state.d.ts +2 -0
  9. package/dist/src/autopilot-state.js +36 -8
  10. package/dist/src/command-resolution.d.ts +15 -0
  11. package/dist/src/command-resolution.js +25 -0
  12. package/dist/src/commands/agent.js +17 -17
  13. package/dist/src/commands/claims.js +6 -8
  14. package/dist/src/commands/daemon.js +94 -33
  15. package/dist/src/commands/doctor.js +95 -18
  16. package/dist/src/commands/memory.js +14 -2
  17. package/dist/src/commands/policy.js +6 -1
  18. package/dist/src/commands/security-code-patterns.d.ts +2 -2
  19. package/dist/src/commands/security-code-patterns.js +61 -3
  20. package/dist/src/commands/security.d.ts +24 -0
  21. package/dist/src/commands/security.js +81 -35
  22. package/dist/src/commands/tui.d.ts +9 -0
  23. package/dist/src/commands/tui.js +29 -3
  24. package/dist/src/config/proven-config-refresh.d.ts +9 -0
  25. package/dist/src/config/proven-config-refresh.js +24 -3
  26. package/dist/src/funnel/local-signals.js +2 -1
  27. package/dist/src/index.js +11 -47
  28. package/dist/src/init/settings-generator.js +4 -58
  29. package/dist/src/init/types.js +1 -1
  30. package/dist/src/mcp-tools/agent-execute-core.d.ts +2 -0
  31. package/dist/src/mcp-tools/agent-execute-core.js +15 -0
  32. package/dist/src/mcp-tools/agent-health-metrics.d.ts +22 -0
  33. package/dist/src/mcp-tools/agent-health-metrics.js +33 -0
  34. package/dist/src/mcp-tools/agent-tools.js +45 -22
  35. package/dist/src/mcp-tools/agentbbs-federation.d.ts +1 -1
  36. package/dist/src/mcp-tools/agentbbs-federation.js +7 -2
  37. package/dist/src/mcp-tools/agentdb-tools.js +25 -2
  38. package/dist/src/mcp-tools/aidefence-known-misses.d.ts +22 -0
  39. package/dist/src/mcp-tools/aidefence-known-misses.js +57 -0
  40. package/dist/src/mcp-tools/analyze-tools.js +10 -11
  41. package/dist/src/mcp-tools/autopilot-tools.js +2 -2
  42. package/dist/src/mcp-tools/browser-intent-tools.js +6 -2
  43. package/dist/src/mcp-tools/embeddings-tools.js +29 -7
  44. package/dist/src/mcp-tools/hooks-tools.js +4 -0
  45. package/dist/src/mcp-tools/memory-tools.d.ts +1 -1
  46. package/dist/src/mcp-tools/memory-tools.js +100 -25
  47. package/dist/src/mcp-tools/metaharness-tools.js +1 -1
  48. package/dist/src/mcp-tools/neural-tools.js +48 -54
  49. package/dist/src/mcp-tools/policy-tools.js +5 -3
  50. package/dist/src/mcp-tools/ruvllm-tools.js +6 -0
  51. package/dist/src/mcp-tools/security-tools.js +55 -17
  52. package/dist/src/mcp-tools/workflow-tools.js +66 -17
  53. package/dist/src/memory/intelligence.d.ts +5 -1
  54. package/dist/src/memory/intelligence.js +158 -35
  55. package/dist/src/memory/memory-bridge.js +10 -3
  56. package/dist/src/memory/memory-initializer.js +2 -1
  57. package/dist/src/memory/search-defaults.d.ts +54 -0
  58. package/dist/src/memory/search-defaults.js +37 -0
  59. package/dist/src/memory/sona-optimizer.d.ts +28 -0
  60. package/dist/src/memory/sona-optimizer.js +59 -2
  61. package/dist/src/memory/stats-file-lock.d.ts +7 -0
  62. package/dist/src/memory/stats-file-lock.js +53 -0
  63. package/dist/src/mods/command-registry/schema.d.ts +24 -24
  64. package/dist/src/ruvector/agent-wasm.d.ts +10 -0
  65. package/dist/src/ruvector/agent-wasm.js +27 -1
  66. package/dist/src/ruvector/diff-classifier.d.ts +2 -4
  67. package/dist/src/ruvector/diff-classifier.js +202 -69
  68. package/dist/src/ruvector/ruvllm-wasm.d.ts +4 -0
  69. package/dist/src/ruvector/ruvllm-wasm.js +12 -1
  70. package/dist/src/services/distill-oracle.d.ts +1 -1
  71. package/dist/src/services/distill-oracle.js +2 -2
  72. package/dist/src/services/policy-anchor-log.d.ts +13 -0
  73. package/dist/src/services/policy-anchor-log.js +242 -0
  74. package/dist/src/services/policy-archive-scan.d.ts +7 -0
  75. package/dist/src/services/policy-archive-scan.js +50 -0
  76. package/dist/src/services/policy-ledger-anchor.d.ts +14 -8
  77. package/dist/src/services/policy-ledger-anchor.js +356 -40
  78. package/dist/src/services/policy-ledger-audit.d.ts +22 -0
  79. package/dist/src/services/policy-ledger-audit.js +260 -0
  80. package/dist/src/services/policy-ledger-record.d.ts +3 -0
  81. package/dist/src/services/policy-ledger-record.js +22 -0
  82. package/dist/src/services/policy-runtime.d.ts +2 -1
  83. package/dist/src/services/policy-runtime.js +267 -40
  84. package/dist/src/services/worker-daemon.d.ts +11 -0
  85. package/dist/src/services/worker-daemon.js +37 -0
  86. package/dist/src/transfer/store/discovery.js +16 -17
  87. package/dist/src/transfer/store/types.d.ts +4 -0
  88. package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
  89. package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
  90. package/node_modules/@claude-flow/security/dist/policy/engine.d.ts +17 -1
  91. package/node_modules/@claude-flow/security/dist/policy/engine.d.ts.map +1 -1
  92. package/node_modules/@claude-flow/security/dist/policy/engine.js +99 -24
  93. package/node_modules/@claude-flow/security/dist/policy/engine.js.map +1 -1
  94. package/node_modules/@claude-flow/security/dist/policy/types.d.ts +14 -1
  95. package/node_modules/@claude-flow/security/dist/policy/types.d.ts.map +1 -1
  96. package/node_modules/@claude-flow/security/dist/policy/types.js +3 -1
  97. package/node_modules/@claude-flow/security/dist/policy/types.js.map +1 -1
  98. package/package.json +5 -5
  99. package/plugins/ruflo-console/dist/tui.mjs +162 -161
  100. package/plugins/ruflo-metaharness/hooks/screen.ts +7 -1
  101. package/plugins/ruflo-metaharness/scripts/_darwin.mjs +4 -4
@@ -0,0 +1,260 @@
1
+ /** Bounded-memory full policy audit. The caller owns the captured archive FD.
2
+ * Only bytes below its locked snapshot boundary are read; normal later appends
3
+ * do not join the audit. Disk scratch is private, disposable, never ledger state.
4
+ */
5
+ import { AgenticPolicyEngine, canonicalizePolicy } from '@claude-flow/security/policy/index';
6
+ import { createHash } from 'node:crypto';
7
+ import { closeSync, chmodSync, constants, fstatSync, mkdtempSync, openSync, read, readSync, rmSync, writeSync } from 'node:fs';
8
+ import { tmpdir } from 'node:os';
9
+ import { join } from 'node:path';
10
+ import { decodeLedgerRecord, policyLedgerRecordLimit } from './policy-ledger-record.js';
11
+ const CHUNK_BYTES = 64 * 1024;
12
+ const INDEX_BYTES = 48;
13
+ function fail(error) { throw new Error(error); }
14
+ /** Must run under the policy writer lock. O(1), with no whole-file read. */
15
+ export function captureArchiveSnapshot(file) {
16
+ let fd;
17
+ try {
18
+ fd = openSync(file, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
19
+ }
20
+ catch (error) {
21
+ if (error.code === 'ENOENT')
22
+ return undefined;
23
+ fail('policy-ledger-archive-not-regular');
24
+ }
25
+ try {
26
+ const stat = fstatSync(fd);
27
+ if (!stat.isFile() || !Number.isSafeInteger(stat.size) || stat.size < 0)
28
+ fail('policy-ledger-archive-not-regular');
29
+ return { fd, size: stat.size };
30
+ }
31
+ catch (error) {
32
+ closeSync(fd);
33
+ throw error;
34
+ }
35
+ }
36
+ function readAt(fd, buffer, offset, length, position) {
37
+ return new Promise((resolve, reject) => read(fd, buffer, offset, length, position, (error, count) => error ? reject(error) : resolve(count)));
38
+ }
39
+ async function readExact(snapshot, offset, length, limit) {
40
+ if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(length) || length <= 0
41
+ || length > limit || offset > snapshot.size - length)
42
+ fail('policy-ledger-archive-changed');
43
+ const buffer = Buffer.allocUnsafe(length);
44
+ let count = 0;
45
+ while (count < length) {
46
+ const next = await readAt(snapshot.fd, buffer, count, length - count, offset + count);
47
+ if (!next)
48
+ fail('policy-ledger-archive-changed');
49
+ count += next;
50
+ }
51
+ return buffer;
52
+ }
53
+ async function* records(snapshot, limit) {
54
+ const chunk = Buffer.allocUnsafe(CHUNK_BYTES);
55
+ let position = 0;
56
+ let recordStart = 0;
57
+ let parts = [];
58
+ let partBytes = 0;
59
+ while (position < snapshot.size) {
60
+ const count = await readAt(snapshot.fd, chunk, 0, Math.min(chunk.length, snapshot.size - position), position);
61
+ if (!count)
62
+ fail('policy-ledger-archive-changed');
63
+ let cursor = 0;
64
+ while (cursor < count) {
65
+ const newline = chunk.indexOf(10, cursor);
66
+ const end = newline < 0 || newline >= count ? count : newline;
67
+ const piece = chunk.subarray(cursor, end);
68
+ partBytes += piece.length;
69
+ if (partBytes > limit)
70
+ fail(`policy-ledger-archive-record-too-large:${limit}`);
71
+ if (end === count) {
72
+ parts.push(Buffer.from(piece));
73
+ break;
74
+ }
75
+ const bytes = parts.length ? Buffer.concat([...parts, piece], partBytes) : Buffer.from(piece);
76
+ yield { bytes, offset: recordStart };
77
+ recordStart = position + end + 1;
78
+ parts = [];
79
+ partBytes = 0;
80
+ cursor = end + 1;
81
+ }
82
+ position += count;
83
+ }
84
+ if (partBytes !== 0)
85
+ fail('policy-ledger-archive-parse-error');
86
+ }
87
+ function parsed(bytes) {
88
+ const text = decodeLedgerRecord(bytes);
89
+ if (!text.trim())
90
+ return undefined;
91
+ try {
92
+ return JSON.parse(text);
93
+ }
94
+ catch {
95
+ fail('policy-ledger-archive-parse-error');
96
+ }
97
+ }
98
+ const digest = (canonical) => createHash('sha256').update(canonical).digest();
99
+ function writeAll(fd, bytes, position) {
100
+ let count = 0;
101
+ while (count < bytes.length) {
102
+ const next = writeSync(fd, bytes, count, bytes.length - count, position + count);
103
+ if (!next)
104
+ fail('policy-ledger-audit-index-write-error');
105
+ count += next;
106
+ }
107
+ }
108
+ function readIndex(fd, sequence) {
109
+ const position = sequence * INDEX_BYTES;
110
+ if (!Number.isSafeInteger(position))
111
+ fail('policy-ledger-archive-gap');
112
+ const row = Buffer.alloc(INDEX_BYTES);
113
+ const count = readSync(fd, row, 0, row.length, position);
114
+ if (count !== 0 && count !== row.length)
115
+ fail('policy-ledger-audit-index-read-error');
116
+ return row;
117
+ }
118
+ async function observedRecord(snapshot, row, limit, verifier) {
119
+ const offsetBig = row.readBigUInt64LE(0);
120
+ if (offsetBig > BigInt(Number.MAX_SAFE_INTEGER))
121
+ fail('policy-ledger-audit-index-read-error');
122
+ const bytes = await readExact(snapshot, Number(offsetBig), row.readUInt32LE(8), limit);
123
+ const receipt = parsed(bytes);
124
+ if (!receipt || verifier.verifyReceipt(receipt))
125
+ fail('policy-ledger-archive-conflict');
126
+ const canonical = canonicalizePolicy(receipt);
127
+ if (!digest(canonical).equals(row.subarray(16)))
128
+ fail('policy-ledger-archive-changed');
129
+ return { receipt, canonical };
130
+ }
131
+ /** Every physical record is authenticated before deduplication, including
132
+ * unclaimed staging records. The fixed-width index only addresses the bounded
133
+ * snapshot's claimed prefix; arbitrary extra sequence numbers never set sparse
134
+ * file offsets. Exact full canonical equality is checked on duplicate rereads.
135
+ * Scratch I/O is disposable and does not need fsync or mutate the ledger.
136
+ */
137
+ export async function verifyFullPolicyLedger(snapshot, state, engineOptions) {
138
+ const retainedFrom = state.retainedFrom ?? 0;
139
+ const length = retainedFrom + state.receipts.length;
140
+ let scratch;
141
+ let index;
142
+ try {
143
+ const limit = policyLedgerRecordLimit();
144
+ if (!Number.isSafeInteger(retainedFrom) || retainedFrom < 0 || !Number.isSafeInteger(length))
145
+ fail('policy-ledger-archive-gap');
146
+ if (!snapshot) {
147
+ if (retainedFrom > 0)
148
+ fail('policy-ledger-archive-gap');
149
+ return AgenticPolicyEngine.fromState(state, engineOptions).verifyLedger();
150
+ }
151
+ // At least one byte must exist for each claimed receipt. This also rejects
152
+ // malicious sparse-index lengths before creating scratch or replay loops.
153
+ if (retainedFrom > snapshot.size)
154
+ fail('policy-ledger-archive-gap');
155
+ if (fstatSync(snapshot.fd).size < snapshot.size)
156
+ fail('policy-ledger-archive-changed');
157
+ scratch = mkdtempSync(join(tmpdir(), 'ruflo-policy-audit-'));
158
+ chmodSync(scratch, 0o700);
159
+ index = openSync(join(scratch, 'index'), 'wx+', 0o600);
160
+ const verifier = new AgenticPolicyEngine(engineOptions);
161
+ let claimedUnique = 0;
162
+ for await (const physical of records(snapshot, limit)) {
163
+ const receipt = parsed(physical.bytes);
164
+ if (receipt === undefined)
165
+ continue;
166
+ if (verifier.verifyReceipt(receipt))
167
+ fail('policy-ledger-archive-conflict');
168
+ const sequence = receipt.payload.sequence;
169
+ const canonical = canonicalizePolicy(receipt);
170
+ if (sequence < retainedFrom) {
171
+ const row = readIndex(index, sequence);
172
+ if (row.readUInt32LE(8) !== 0) {
173
+ const first = await observedRecord(snapshot, row, limit, verifier);
174
+ if (first.canonical !== canonical)
175
+ fail('policy-ledger-archive-conflict');
176
+ }
177
+ else {
178
+ row.writeBigUInt64LE(BigInt(physical.offset), 0);
179
+ row.writeUInt32LE(physical.bytes.length, 8);
180
+ digest(canonical).copy(row, 16);
181
+ writeAll(index, row, sequence * INDEX_BYTES);
182
+ claimedUnique++;
183
+ }
184
+ }
185
+ else if (sequence < length) {
186
+ if (canonicalizePolicy(state.receipts[sequence - retainedFrom]) !== canonical)
187
+ fail('policy-ledger-archive-conflict');
188
+ }
189
+ else {
190
+ // Rare, unclaimed staging extras are still authenticated and deduped;
191
+ // decimal safe-integer names never choose a path or a sparse offset.
192
+ const file = join(scratch, `extra-${sequence}`);
193
+ const canonicalBytes = Buffer.from(canonical);
194
+ let fd;
195
+ try {
196
+ fd = openSync(file, 'wx', 0o600);
197
+ }
198
+ catch (error) {
199
+ if (error.code !== 'EEXIST')
200
+ throw error;
201
+ fd = openSync(file, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
202
+ try {
203
+ const stat = fstatSync(fd);
204
+ if (!stat.isFile())
205
+ fail('policy-ledger-audit-index-read-error');
206
+ // Canonical finite numbers can expand beyond a fixed multiple of
207
+ // raw input bytes. Compare the already-bounded incoming value's
208
+ // exact encoded length before allocating any scratch read buffer.
209
+ if (stat.size !== canonicalBytes.length)
210
+ fail('policy-ledger-archive-conflict');
211
+ const stored = Buffer.alloc(stat.size);
212
+ if (readSync(fd, stored, 0, stored.length, 0) !== stored.length || !stored.equals(canonicalBytes))
213
+ fail('policy-ledger-archive-conflict');
214
+ }
215
+ finally {
216
+ closeSync(fd);
217
+ }
218
+ continue;
219
+ }
220
+ try {
221
+ writeAll(fd, canonicalBytes, 0);
222
+ }
223
+ finally {
224
+ closeSync(fd);
225
+ }
226
+ }
227
+ }
228
+ if (claimedUnique !== retainedFrom)
229
+ fail('policy-ledger-archive-gap');
230
+ let previous = null;
231
+ for (let sequence = 0; sequence < retainedFrom; sequence++) {
232
+ const row = readIndex(index, sequence);
233
+ if (!row.readUInt32LE(8))
234
+ fail('policy-ledger-archive-gap');
235
+ const { receipt } = await observedRecord(snapshot, row, limit, verifier);
236
+ if (receipt.payload.sequence !== sequence || receipt.payload.previousReceiptHash !== previous)
237
+ fail('receipt-chain-mismatch');
238
+ previous = receipt.hash;
239
+ }
240
+ if (retainedFrom > 0 && previous !== state.prunedHead)
241
+ fail('receipt-chain-mismatch');
242
+ const hot = AgenticPolicyEngine.fromState(state, engineOptions).verifyLedger();
243
+ if (!hot.valid)
244
+ return hot;
245
+ if (fstatSync(snapshot.fd).size < snapshot.size)
246
+ fail('policy-ledger-archive-changed');
247
+ return hot;
248
+ }
249
+ catch (error) {
250
+ const message = error.message;
251
+ return { valid: false, length, error: message.startsWith('policy-ledger-') || message === 'receipt-chain-mismatch' ? message : 'policy-ledger-audit-io-error' };
252
+ }
253
+ finally {
254
+ if (index !== undefined)
255
+ closeSync(index);
256
+ if (scratch !== undefined)
257
+ rmSync(scratch, { recursive: true, force: true });
258
+ }
259
+ }
260
+ //# sourceMappingURL=policy-ledger-audit.js.map
@@ -0,0 +1,3 @@
1
+ export declare function policyLedgerRecordLimit(): number;
2
+ export declare function decodeLedgerRecord(bytes: Buffer): string;
3
+ //# sourceMappingURL=policy-ledger-record.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { TextDecoder } from 'node:util';
2
+ const DEFAULT_LIMIT = 16 * 1024 * 1024;
3
+ const MAX_LIMIT = 64 * 1024 * 1024;
4
+ const decoder = new TextDecoder('utf-8', { fatal: true });
5
+ export function policyLedgerRecordLimit() {
6
+ const raw = process.env.CLAUDE_FLOW_POLICY_AUDIT_MAX_RECORD_BYTES;
7
+ if (!raw)
8
+ return DEFAULT_LIMIT;
9
+ const value = Number(raw);
10
+ if (!Number.isSafeInteger(value) || value < 1024 || value > MAX_LIMIT)
11
+ throw new Error('policy-ledger-audit-invalid-record-limit');
12
+ return value;
13
+ }
14
+ export function decodeLedgerRecord(bytes) {
15
+ try {
16
+ return decoder.decode(bytes);
17
+ }
18
+ catch {
19
+ throw new Error('policy-ledger-archive-utf8-error');
20
+ }
21
+ }
22
+ //# sourceMappingURL=policy-ledger-record.js.map
@@ -1,4 +1,4 @@
1
- import { AgenticPolicyEngine, type BudgetLimit, type CapabilityEnvelope, type PolicyApproval, type PolicyDecision, type PolicyRequest, type PolicyRule, type PolicyState } from '@claude-flow/security';
1
+ import { AgenticPolicyEngine, type BudgetLimit, type CapabilityEnvelope, type PolicyApproval, type PolicyDecision, type PolicyRequest, type PolicyRule, type PolicyState } from '@claude-flow/security/policy/index';
2
2
  /**
3
3
  * Exported for ADR-406 mission storage, which takes the same per-file lock
4
4
  * (pid, pid namespace and boot id identify a dead owner) rather than a copy.
@@ -34,6 +34,7 @@ export type PolicyLedgerVerification = ReturnType<AgenticPolicyEngine['verifyLed
34
34
  */
35
35
  export declare function verifyPolicyLedger(projectRoot?: string, options?: {
36
36
  establishAnchor?: boolean;
37
+ full?: boolean;
37
38
  }): Promise<PolicyLedgerVerification>;
38
39
  export declare function authorizeMcpTool(toolName: string, input: Record<string, unknown>, context?: Record<string, unknown>, attributes?: Readonly<{
39
40
  actionType?: string;