@claude-flow/cli 3.32.30 → 3.32.32

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": {
3
- "version": "3.32.30",
3
+ "version": "3.32.32",
4
4
  "files": {
5
5
  "auto-memory-hook.mjs": "68be7e9a9eba7bf9c4e8a230db7bf61a243b965639f8504842799d6c6ca28762",
6
6
  "hook-handler.cjs": "50ea92a72651bdc95634f7588d56a5870963168eef5226f66ed14af3b47c8d9a",
@@ -8,6 +8,6 @@
8
8
  "statusline.cjs": "d2a0eac56d1267d8dbed2d70b09feb592299469196ec4b215909f2b052144882"
9
9
  }
10
10
  },
11
- "signature": "6wQg/DXPVzG1hEnZzI0RcEi/6wfUnXyFYZ09Ho7jVHz84sbuX1flCWZA3qq5c8BvUtZ9/oCs9GOpEnMykGk4CA==",
11
+ "signature": "04DvDI9kCGvy1HIskgegJsTnGUTgnDBMGTb/c+ef/hy3XgM4WvpHb6xePaWraB6YQ4F41+4BZRi4ZeBWBrVbBA==",
12
12
  "algorithm": "ed25519"
13
13
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "generation": 3,
4
- "generatedAt": "2026-07-29T05:35:40.000Z",
5
- "gitSha": "1385e21b",
4
+ "generatedAt": "2026-07-29T12:41:44.000Z",
5
+ "gitSha": "388849b3",
6
6
  "catalog": {
7
7
  "agents": 164,
8
8
  "tools": 395,
@@ -61,6 +61,16 @@ export declare function validateNumber(value: unknown, min: number, max: number,
61
61
  * Returns only valid sources; falls back to defaults if none are valid.
62
62
  */
63
63
  export declare function validateTaskSources(sources: unknown): string[];
64
+ export type TaskSourceValidation = {
65
+ valid: true;
66
+ sources: string[];
67
+ } | {
68
+ valid: false;
69
+ invalidSources: string[];
70
+ reason: string;
71
+ };
72
+ /** Strictly validate user-supplied task sources without enabling defaults. */
73
+ export declare function validateConfiguredTaskSources(sources: unknown): TaskSourceValidation;
64
74
  export declare function getDefaultState(): AutopilotState;
65
75
  export declare function loadState(): AutopilotState;
66
76
  export declare function saveState(state: AutopilotState): void;
@@ -74,6 +74,22 @@ export function validateTaskSources(sources) {
74
74
  .filter(s => VALID_TASK_SOURCES.has(s));
75
75
  return valid.length > 0 ? valid : defaults;
76
76
  }
77
+ /** Strictly validate user-supplied task sources without enabling defaults. */
78
+ export function validateConfiguredTaskSources(sources) {
79
+ if (!Array.isArray(sources) || sources.length === 0) {
80
+ return { valid: false, invalidSources: [], reason: 'At least one task source is required' };
81
+ }
82
+ const normalized = sources.map(source => typeof source === 'string' ? source.trim() : String(source));
83
+ const invalidSources = normalized.filter(source => !VALID_TASK_SOURCES.has(source));
84
+ if (invalidSources.length > 0) {
85
+ return {
86
+ valid: false,
87
+ invalidSources,
88
+ reason: `Unsupported task source(s): ${invalidSources.join(', ')}`,
89
+ };
90
+ }
91
+ return { valid: true, sources: [...new Set(normalized)] };
92
+ }
77
93
  // ── State Management ──────────────────────────────────────────
78
94
  export function getDefaultState() {
79
95
  return {
@@ -5,7 +5,7 @@
5
5
  * ADR-072: Autopilot Integration
6
6
  */
7
7
  import { output } from '../output.js';
8
- import { loadState, saveState, appendLog, loadLog, discoverTasks, getProgress, calculateReward, tryLoadLearning, validateNumber, validateTaskSources, LOG_FILE, } from '../autopilot-state.js';
8
+ import { loadState, saveState, appendLog, loadLog, discoverTasks, getProgress, calculateReward, tryLoadLearning, validateNumber, validateConfiguredTaskSources, VALID_TASK_SOURCES, LOG_FILE, } from '../autopilot-state.js';
9
9
  import { getCheckpointGate, CheckpointGate } from '../services/checkpoint-gate.js';
10
10
  /**
11
11
  * Opt-in checkpoint/rollback gate for the autopilot tick (agenticow step 3).
@@ -183,7 +183,7 @@ const configCommand = {
183
183
  options: [
184
184
  { name: 'max-iterations', type: 'string', description: 'Max re-engagement iterations (1-1000)' },
185
185
  { name: 'timeout', type: 'string', description: 'Timeout in minutes (1-1440)' },
186
- { name: 'task-sources', type: 'string', description: 'Comma-separated task sources' },
186
+ { name: 'task-sources', type: 'string', description: `Comma-separated task sources: ${[...VALID_TASK_SOURCES].join(', ')}` },
187
187
  ],
188
188
  action: async (ctx) => {
189
189
  const state = loadState();
@@ -194,8 +194,14 @@ const configCommand = {
194
194
  state.maxIterations = validateNumber(maxIter, 1, 1000, state.maxIterations);
195
195
  if (timeout)
196
196
  state.timeoutMinutes = validateNumber(timeout, 1, 1440, state.timeoutMinutes);
197
- if (sources)
198
- state.taskSources = validateTaskSources(sources.split(',').map(s => s.trim()).filter(Boolean));
197
+ if (sources !== undefined) {
198
+ const validation = validateConfiguredTaskSources(sources.split(',').map(s => s.trim()).filter(Boolean));
199
+ if (!validation.valid) {
200
+ output.printError(`${validation.reason}. Valid sources: ${[...VALID_TASK_SOURCES].join(', ')}`);
201
+ return { success: false, exitCode: 1 };
202
+ }
203
+ state.taskSources = validation.sources;
204
+ }
199
205
  saveState(state);
200
206
  appendLog({ ts: Date.now(), event: 'config-updated', maxIterations: state.maxIterations, timeoutMinutes: state.timeoutMinutes, taskSources: state.taskSources });
201
207
  output.writeln(`Config updated: maxIterations=${state.maxIterations}, timeout=${state.timeoutMinutes}min, sources=${state.taskSources.join(',')}`);
@@ -8,7 +8,7 @@
8
8
  * @module @claude-flow/cli/mcp-tools/autopilot
9
9
  */
10
10
  import { validateText } from './validate-input.js';
11
- import { loadState, saveState, appendLog, loadLog, discoverTasks, isTerminal, tryLoadLearning, validateNumber, validateTaskSources, VALID_TASK_SOURCES, } from '../autopilot-state.js';
11
+ import { loadState, saveState, appendLog, loadLog, discoverTasks, isTerminal, tryLoadLearning, validateNumber, validateConfiguredTaskSources, VALID_TASK_SOURCES, } from '../autopilot-state.js';
12
12
  function ok(data) {
13
13
  return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
14
14
  }
@@ -71,7 +71,12 @@ const autopilotConfig = {
71
71
  properties: {
72
72
  maxIterations: { type: 'number', description: 'Max re-engagement iterations (1-1000)' },
73
73
  timeoutMinutes: { type: 'number', description: 'Timeout in minutes (1-1440)' },
74
- taskSources: { type: 'array', items: { type: 'string' }, description: `Task sources: ${[...VALID_TASK_SOURCES].join(', ')}` },
74
+ taskSources: {
75
+ type: 'array',
76
+ minItems: 1,
77
+ items: { type: 'string', enum: [...VALID_TASK_SOURCES] },
78
+ description: `Task sources: ${[...VALID_TASK_SOURCES].join(', ')}`,
79
+ },
75
80
  },
76
81
  },
77
82
  handler: async (params) => {
@@ -83,7 +88,17 @@ const autopilotConfig = {
83
88
  state.timeoutMinutes = validateNumber(params.timeoutMinutes, 1, 1440, state.timeoutMinutes);
84
89
  }
85
90
  if (params.taskSources !== undefined) {
86
- state.taskSources = validateTaskSources(params.taskSources);
91
+ const validation = validateConfiguredTaskSources(params.taskSources);
92
+ if (!validation.valid) {
93
+ return {
94
+ content: [{ type: 'text', text: JSON.stringify({
95
+ error: validation.reason,
96
+ validSources: [...VALID_TASK_SOURCES],
97
+ }) }],
98
+ isError: true,
99
+ };
100
+ }
101
+ state.taskSources = validation.sources;
87
102
  }
88
103
  saveState(state);
89
104
  return ok({ maxIterations: state.maxIterations, timeoutMinutes: state.timeoutMinutes, taskSources: state.taskSources });
@@ -1,6 +1,26 @@
1
1
  import { type FlywheelResult } from './harness-flywheel.js';
2
2
  import { type GenerationResult } from './harness-flywheel-generations.js';
3
- import { type DarwinInvoker, type ProposerMode } from './flywheel-proposer.js';
3
+ import { type DarwinInvoker, type ProposerMode, type SafetyEnvelope } from './flywheel-proposer.js';
4
+ /**
5
+ * The ADR-322 retrieval safety envelope.
6
+ *
7
+ * It MUST describe the policy surface the proposer actually emits —
8
+ * `RetrievalConfig`. The v1 envelope allowed `topK`/`rerank`, which are
9
+ * `neural_patterns` search-call arguments not representable in
10
+ * `RetrievalConfig`, while omitting the three weight axes that
11
+ * `retrievalPolicyNeighbors` does mutate. Because `validateCandidate` checks
12
+ * EVERY key of a candidate policy (candidates are full snapshots, not deltas),
13
+ * that drift made every locally-proposed candidate inadmissible and the local
14
+ * evaluation path unreachable — no receipt, therefore no promotion, ever.
15
+ *
16
+ * Every axis carries a finite bound: an allowed key WITHOUT bounds is an
17
+ * unbounded key, because `validateCandidate` applies bounds only when present.
18
+ * A Darwin proposer could otherwise submit arbitrary weights on the three axes.
19
+ *
20
+ * Exported so tests can bind the REAL envelope to the REAL proposer; the drift
21
+ * survived review precisely because no test wired those two together.
22
+ */
23
+ export declare function retrievalSafetyEnvelope(ref?: string): SafetyEnvelope;
4
24
  /**
5
25
  * Run one live flywheel tick against `projectRoot`. Opt-in + $0 default: with
6
26
  * RUFLO_HARNESS_LOOP unset it is a no-op. Best-effort; never throws.
@@ -24,6 +24,51 @@ const ANCHOR = [
24
24
  ['Q-learning encoder keyword block', ['q-state encoder', 'route q-state', 'keyword block', '#2239', 'q-encoder']],
25
25
  ['security hardening crypto random IDs', ['cwe-347', 'crypto.randomuuid', 'security fix', 'random id', 'crypto random']],
26
26
  ].map(([q, labels], i) => ({ id: `q${String(i).padStart(2, '0')}`, input: { id: `q${String(i).padStart(2, '0')}`, q: q }, expected: labels }));
27
+ /**
28
+ * The ADR-322 retrieval safety envelope.
29
+ *
30
+ * It MUST describe the policy surface the proposer actually emits —
31
+ * `RetrievalConfig`. The v1 envelope allowed `topK`/`rerank`, which are
32
+ * `neural_patterns` search-call arguments not representable in
33
+ * `RetrievalConfig`, while omitting the three weight axes that
34
+ * `retrievalPolicyNeighbors` does mutate. Because `validateCandidate` checks
35
+ * EVERY key of a candidate policy (candidates are full snapshots, not deltas),
36
+ * that drift made every locally-proposed candidate inadmissible and the local
37
+ * evaluation path unreachable — no receipt, therefore no promotion, ever.
38
+ *
39
+ * Every axis carries a finite bound: an allowed key WITHOUT bounds is an
40
+ * unbounded key, because `validateCandidate` applies bounds only when present.
41
+ * A Darwin proposer could otherwise submit arbitrary weights on the three axes.
42
+ *
43
+ * Exported so tests can bind the REAL envelope to the REAL proposer; the drift
44
+ * survived review precisely because no test wired those two together.
45
+ */
46
+ export function retrievalSafetyEnvelope(ref) {
47
+ const allowedPolicyKeys = ['alpha', 'subjectWeight', 'mmrLambda', 'bodyWeight', 'typePenaltyFactor'];
48
+ const numericBounds = {
49
+ alpha: { min: 0.1, max: 0.9 },
50
+ subjectWeight: { min: 0.1, max: 10 },
51
+ mmrLambda: { min: 0.3, max: 0.9 },
52
+ bodyWeight: { min: 0.1, max: 10 },
53
+ typePenaltyFactor: { min: 0.1, max: 10 },
54
+ };
55
+ return {
56
+ ref: ref ?? sha256Ref(JSON.stringify({
57
+ schema: 'ruflo.retrieval-safety-envelope/v2',
58
+ allowedPolicyKeys,
59
+ numericBounds,
60
+ })),
61
+ allowedPolicyKeys,
62
+ numericBounds,
63
+ // Retrieval evaluations are local and report zero provider spend today;
64
+ // finite ceilings make any future resource evidence fail closed.
65
+ maxP95LatencyMicros: 5_000_000,
66
+ maxCostMicrosPerTask: 10_000,
67
+ maxTokensPerTask: 100_000,
68
+ maxFailureRate: 0.01,
69
+ maxEvaluationCostMicros: 1_000_000,
70
+ };
71
+ }
27
72
  /**
28
73
  * Run one live flywheel tick against `projectRoot`. Opt-in + $0 default: with
29
74
  * RUFLO_HARNESS_LOOP unset it is a no-op. Best-effort; never throws.
@@ -53,30 +98,7 @@ export async function runFlywheelWorker(projectRoot, opts = {}) {
53
98
  ...DEFAULT_CONFIG,
54
99
  ...(applier.activeChampion(projectRoot)?.params ?? {}),
55
100
  };
56
- const safetyEnvelope = {
57
- ref: opts.safetyEnvelopeRef ?? sha256Ref(JSON.stringify({
58
- schema: 'ruflo.retrieval-safety-envelope/v1',
59
- allowedPolicyKeys: ['alpha', 'topK', 'rerank', 'mmrLambda'],
60
- numericBounds: {
61
- alpha: { min: 0.1, max: 0.9 },
62
- topK: { min: 5, max: 20 },
63
- mmrLambda: { min: 0.3, max: 0.9 },
64
- },
65
- })),
66
- allowedPolicyKeys: ['alpha', 'topK', 'rerank', 'mmrLambda'],
67
- numericBounds: {
68
- alpha: { min: 0.1, max: 0.9 },
69
- topK: { min: 5, max: 20 },
70
- mmrLambda: { min: 0.3, max: 0.9 },
71
- },
72
- // Retrieval evaluations are local and report zero provider spend today;
73
- // finite ceilings make any future resource evidence fail closed.
74
- maxP95LatencyMicros: 5_000_000,
75
- maxCostMicrosPerTask: 10_000,
76
- maxTokensPerTask: 100_000,
77
- maxFailureRate: 0.01,
78
- maxEvaluationCostMicros: 1_000_000,
79
- };
101
+ const safetyEnvelope = retrievalSafetyEnvelope(opts.safetyEnvelopeRef);
80
102
  // CLI flag opts.proposer takes precedence over RUFLO_FLYWHEEL_PROPOSER.
81
103
  const proposerMode = opts.proposer
82
104
  ?? (process.env.RUFLO_FLYWHEEL_PROPOSER ?? 'auto');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-flow/cli",
3
- "version": "3.32.30",
3
+ "version": "3.32.32",
4
4
  "type": "module",
5
5
  "description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",