claude-flow 3.55.0 → 3.56.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 (64) hide show
  1. package/.claude/settings.json +0 -1
  2. package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
  3. package/node_modules/@claude-flow/security/dist/oauth/callback-server.d.ts +2 -1
  4. package/node_modules/@claude-flow/security/dist/oauth/callback-server.d.ts.map +1 -1
  5. package/node_modules/@claude-flow/security/dist/oauth/callback-server.js +48 -16
  6. package/node_modules/@claude-flow/security/dist/oauth/callback-server.js.map +1 -1
  7. package/node_modules/@claude-flow/security/dist/path-validator.d.ts +2 -2
  8. package/node_modules/@claude-flow/security/dist/path-validator.d.ts.map +1 -1
  9. package/node_modules/@claude-flow/security/dist/path-validator.js +15 -4
  10. package/node_modules/@claude-flow/security/dist/path-validator.js.map +1 -1
  11. package/node_modules/@claude-flow/security/package.json +1 -1
  12. package/package.json +2 -2
  13. package/v3/@claude-flow/cli/catalog-manifest.json +2 -2
  14. package/v3/@claude-flow/cli/dist/src/auth/client.js +40 -24
  15. package/v3/@claude-flow/cli/dist/src/commands/agent.js +12 -0
  16. package/v3/@claude-flow/cli/dist/src/commands/analyze.js +18 -14
  17. package/v3/@claude-flow/cli/dist/src/commands/daemon.js +11 -19
  18. package/v3/@claude-flow/cli/dist/src/commands/doctor.js +65 -58
  19. package/v3/@claude-flow/cli/dist/src/commands/memory-backup.d.ts +1 -1
  20. package/v3/@claude-flow/cli/dist/src/commands/memory-backup.js +23 -9
  21. package/v3/@claude-flow/cli/dist/src/commands/memory.d.ts +0 -4
  22. package/v3/@claude-flow/cli/dist/src/commands/memory.js +10 -2
  23. package/v3/@claude-flow/cli/dist/src/commands/plugins.js +13 -1
  24. package/v3/@claude-flow/cli/dist/src/commands/task.js +12 -0
  25. package/v3/@claude-flow/cli/dist/src/init/settings-generator.js +3 -3
  26. package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-execute-core.js +244 -188
  27. package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-tools.js +15 -16
  28. package/v3/@claude-flow/cli/dist/src/mcp-tools/agentdb-tools.js +22 -3
  29. package/v3/@claude-flow/cli/dist/src/mcp-tools/claims-tools.js +3 -11
  30. package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +47 -2
  31. package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +29 -10
  32. package/v3/@claude-flow/cli/dist/src/mcp-tools/record-store.d.ts +3 -0
  33. package/v3/@claude-flow/cli/dist/src/mcp-tools/record-store.js +21 -0
  34. package/v3/@claude-flow/cli/dist/src/mcp-tools/session-tools.js +47 -13
  35. package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +5 -11
  36. package/v3/@claude-flow/cli/dist/src/mcp-tools/workflow-tools.js +78 -29
  37. package/v3/@claude-flow/cli/dist/src/memory/append-conditions.d.ts +28 -0
  38. package/v3/@claude-flow/cli/dist/src/memory/append-conditions.js +56 -0
  39. package/v3/@claude-flow/cli/dist/src/memory/graph-edge-writer.d.ts +9 -0
  40. package/v3/@claude-flow/cli/dist/src/memory/graph-edge-writer.js +90 -0
  41. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.d.ts +4 -0
  42. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +50 -9
  43. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +4 -0
  44. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +95 -61
  45. package/v3/@claude-flow/cli/dist/src/memory/memory-root.d.ts +2 -0
  46. package/v3/@claude-flow/cli/dist/src/memory/memory-root.js +28 -0
  47. package/v3/@claude-flow/cli/dist/src/memory/sona-optimizer.d.ts +2 -0
  48. package/v3/@claude-flow/cli/dist/src/memory/sona-optimizer.js +4 -0
  49. package/v3/@claude-flow/cli/dist/src/parser.js +7 -0
  50. package/v3/@claude-flow/cli/dist/src/plugins/store/discovery.d.ts +6 -0
  51. package/v3/@claude-flow/cli/dist/src/plugins/store/discovery.js +7 -3
  52. package/v3/@claude-flow/cli/dist/src/ruvector/neural-router.js +7 -2
  53. package/v3/@claude-flow/cli/dist/src/services/claim-service.js +39 -18
  54. package/v3/@claude-flow/cli/dist/src/services/claims-store.d.ts +3 -0
  55. package/v3/@claude-flow/cli/dist/src/services/claims-store.js +40 -0
  56. package/v3/@claude-flow/cli/dist/src/services/distill-tuning.js +17 -10
  57. package/v3/@claude-flow/cli/dist/src/services/memory-backup.d.ts +7 -0
  58. package/v3/@claude-flow/cli/dist/src/services/memory-backup.js +29 -2
  59. package/v3/@claude-flow/cli/dist/src/services/memory-distillation.js +2 -2
  60. package/v3/@claude-flow/cli/dist/src/services/worker-daemon.d.ts +4 -2
  61. package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +14 -6
  62. package/v3/@claude-flow/cli/package.json +4 -4
  63. package/.claude/.proven-config-version +0 -1
  64. package/.claude/proven-config.json +0 -42
@@ -7,7 +7,7 @@
7
7
  import { output } from '../output.js';
8
8
  import { existsSync, readFileSync, statSync, openSync, readSync, closeSync } from 'fs';
9
9
  import { join, dirname } from 'path';
10
- import { fileURLToPath } from 'url';
10
+ import { fileURLToPath, pathToFileURL } from 'url';
11
11
  import { createHash } from 'crypto';
12
12
  import { execSync, exec, execFile } from 'child_process';
13
13
  import { promisify } from 'util';
@@ -2117,7 +2117,7 @@ async function checkMetaharnessIntegration() {
2117
2117
  // Runtime smoke: import the similarity module and exercise it
2118
2118
  try {
2119
2119
  const modPath = join(pluginDir, 'scripts', '_similarity.mjs');
2120
- const mod = await import(modPath);
2120
+ const mod = await import(pathToFileURL(modPath).href);
2121
2121
  if (typeof mod.similarity !== 'function') {
2122
2122
  return {
2123
2123
  name: 'MetaHarness integration (ADR-150)',
@@ -2144,7 +2144,7 @@ async function checkMetaharnessIntegration() {
2144
2144
  // parallelization primitives oia-audit depends on; if they're
2145
2145
  // missing, oia-audit's import fails and the whole pipeline breaks.
2146
2146
  const harnessPath = join(pluginDir, 'scripts', '_harness.mjs');
2147
- const harnessMod = await import(harnessPath);
2147
+ const harnessMod = await import(pathToFileURL(harnessPath).href);
2148
2148
  if (typeof harnessMod.parseMcpScanText !== 'function') {
2149
2149
  return {
2150
2150
  name: 'MetaHarness integration (ADR-150)',
@@ -2580,6 +2580,67 @@ export const doctorCommand = {
2580
2580
  const verbose = ctx.flags.verbose;
2581
2581
  // Parser camelCases kebab-case flag names — read via `fixHandles`, not `['fix-handles']`.
2582
2582
  const fixHandles = ctx.flags.fixHandles;
2583
+ // #2677: `--component memory` now runs the whole memory-health suite,
2584
+ // not just the existence check. Values can be a single check or an
2585
+ // array — expanded at execution time. Stuinfla's report showed the
2586
+ // existence-only check reporting PASS on a 99.97%-empty and even a
2587
+ // SQLite-malformed DB; the array here layers integrity → content →
2588
+ // embedding coverage over the existing existence probe; check 6 then
2589
+ // verifies that distilled episodes are actually Reflexion-retrievable and
2590
+ // execution feedback carries a lesson.
2591
+ const componentMap = {
2592
+ 'version': checkVersionFreshness,
2593
+ 'freshness': checkVersionFreshness,
2594
+ 'node': checkNodeVersion,
2595
+ 'npm': checkNpmVersion,
2596
+ 'claude': checkClaudeCode,
2597
+ 'browser': checkAgentBrowserVersion,
2598
+ 'config': checkConfigFile,
2599
+ 'stale-settings': checkStaleSettingsNpx, // #2448
2600
+ 'helpers': () => checkHelperIntegrity(), // #3565
2601
+ 'daemon': checkDaemonStatus,
2602
+ get memory() {
2603
+ return [
2604
+ checkMemoryDatabase, // existing: exists + statable (unchanged)
2605
+ checkMemoryIntegrity, // #2677 check 1: sql.js open + PRAGMA integrity_check
2606
+ ...nativeAgentDbChecks, // #3195: present AgentDB authority, checked independently
2607
+ checkMemoryPersistenceDriver, // #2968/#3321: read-only native capability probe
2608
+ checkMemoryPackageVersion, // #3392: loaded memory package satisfies the declared range
2609
+ checkMemoryContent, // #2677 check 2: memory_entries content coverage
2610
+ checkMemoryEmbeddingCoverage, // #2677 check 3: vector coverage on populated rows
2611
+ checkMemoryReflexionCoverage, // #2677 check 6: episodes are retrievable
2612
+ checkMemoryCritiqueCoverage, // #2677 check 6: feedback carries lessons
2613
+ ];
2614
+ },
2615
+ 'memory-package': checkMemoryPackageVersion, // #3392
2616
+ 'learning': checkLearningBridge, // #2545
2617
+ 'learning-bridge': checkLearningBridge, // #2545
2618
+ 'api': checkApiKeys,
2619
+ 'git': checkGit,
2620
+ 'mcp': checkMcpServers,
2621
+ 'mcp-overhead': checkMcpSchemaOverhead,
2622
+ 'aidefence': checkAIDefence, // #1807
2623
+ 'disk': checkDiskSpace,
2624
+ 'typescript': checkBuildTools,
2625
+ 'agentic-flow': checkAgenticFlow,
2626
+ 'encryption': checkEncryptionAtRest, // ADR-096 Phase 5
2627
+ 'federation': checkFederationBreaker, // ADR-097 Phase 4
2628
+ 'metaharness': [checkMetaharness, checkMetaharnessDeclaredPackages, checkMetaharnessIntegration], // ADR-150 — upstream + declared deps + ruflo-side
2629
+ 'metaharness-integration': checkMetaharnessIntegration, // iter 45 — ruflo-side
2630
+ 'funnel': checkFunnel, // ADR-305
2631
+ // ADR-307 — deep-dive array, same pattern as 'memory' above: the cheap
2632
+ // sponsored-consent check first, then binary/process/bind in the order
2633
+ // a user would actually debug them (is it installed? running? exposed?).
2634
+ 'proxy': [checkProxySponsoredConsent, checkProxyBinary, checkProxyProcess, checkProxyBindAddress],
2635
+ 'auth': checkAuth, // ADR-306
2636
+ 'typesafe': checkTypesafeRouter, // opt-in @ruvector/typesafe task router
2637
+ 'mods': checkMods, // ADR-404 — ruflo as a Claude Code mod
2638
+ };
2639
+ if (component !== undefined && !Object.hasOwn(componentMap, component)) {
2640
+ const message = `Unknown doctor component: ${JSON.stringify(component)}. Valid components: ${Object.keys(componentMap).join(', ')}`;
2641
+ output.printError(message);
2642
+ return { success: false, exitCode: 1, message };
2643
+ }
2583
2644
  // Early-return short-circuit: `--fix-handles` is a targeted mitigation, not
2584
2645
  // part of the health-check flow. Runs, reports, exits.
2585
2646
  if (fixHandles) {
@@ -2684,62 +2745,8 @@ export const doctorCommand = {
2684
2745
  checkAuth, // ADR-306 — Cognitum identity (warn-only; never fails bare `ruflo doctor`)
2685
2746
  checkMods, // ADR-404 — Claude Code mod path (warn-only)
2686
2747
  ];
2687
- // #2677: `--component memory` now runs the whole memory-health suite,
2688
- // not just the existence check. Values can be a single check or an
2689
- // array — expanded at execution time. Stuinfla's report showed the
2690
- // existence-only check reporting PASS on a 99.97%-empty and even a
2691
- // SQLite-malformed DB; the array here layers integrity → content →
2692
- // embedding coverage over the existing existence probe; check 6 then
2693
- // verifies that distilled episodes are actually Reflexion-retrievable and
2694
- // execution feedback carries a lesson.
2695
- const componentMap = {
2696
- 'version': checkVersionFreshness,
2697
- 'freshness': checkVersionFreshness,
2698
- 'node': checkNodeVersion,
2699
- 'npm': checkNpmVersion,
2700
- 'claude': checkClaudeCode,
2701
- 'browser': checkAgentBrowserVersion,
2702
- 'config': checkConfigFile,
2703
- 'stale-settings': checkStaleSettingsNpx, // #2448
2704
- 'helpers': () => checkHelperIntegrity(), // #3565
2705
- 'daemon': checkDaemonStatus,
2706
- 'memory': [
2707
- checkMemoryDatabase, // existing: exists + statable (unchanged)
2708
- checkMemoryIntegrity, // #2677 check 1: sql.js open + PRAGMA integrity_check
2709
- ...nativeAgentDbChecks, // #3195: present AgentDB authority, checked independently
2710
- checkMemoryPersistenceDriver, // #2968/#3321: read-only native capability probe
2711
- checkMemoryPackageVersion, // #3392: loaded memory package satisfies the declared range
2712
- checkMemoryContent, // #2677 check 2: memory_entries content coverage
2713
- checkMemoryEmbeddingCoverage, // #2677 check 3: vector coverage on populated rows
2714
- checkMemoryReflexionCoverage, // #2677 check 6: episodes are retrievable
2715
- checkMemoryCritiqueCoverage, // #2677 check 6: feedback carries lessons
2716
- ],
2717
- 'memory-package': checkMemoryPackageVersion, // #3392
2718
- 'learning': checkLearningBridge, // #2545
2719
- 'learning-bridge': checkLearningBridge, // #2545
2720
- 'api': checkApiKeys,
2721
- 'git': checkGit,
2722
- 'mcp': checkMcpServers,
2723
- 'mcp-overhead': checkMcpSchemaOverhead,
2724
- 'aidefence': checkAIDefence, // #1807
2725
- 'disk': checkDiskSpace,
2726
- 'typescript': checkBuildTools,
2727
- 'agentic-flow': checkAgenticFlow,
2728
- 'encryption': checkEncryptionAtRest, // ADR-096 Phase 5
2729
- 'federation': checkFederationBreaker, // ADR-097 Phase 4
2730
- 'metaharness': [checkMetaharness, checkMetaharnessDeclaredPackages, checkMetaharnessIntegration], // ADR-150 — upstream + declared deps + ruflo-side
2731
- 'metaharness-integration': checkMetaharnessIntegration, // iter 45 — ruflo-side
2732
- 'funnel': checkFunnel, // ADR-305
2733
- // ADR-307 — deep-dive array, same pattern as 'memory' above: the cheap
2734
- // sponsored-consent check first, then binary/process/bind in the order
2735
- // a user would actually debug them (is it installed? running? exposed?).
2736
- 'proxy': [checkProxySponsoredConsent, checkProxyBinary, checkProxyProcess, checkProxyBindAddress],
2737
- 'auth': checkAuth, // ADR-306
2738
- 'typesafe': checkTypesafeRouter, // opt-in @ruvector/typesafe task router
2739
- 'mods': checkMods, // ADR-404 — ruflo as a Claude Code mod
2740
- };
2741
2748
  let checksToRun = allChecks;
2742
- if (component && componentMap[component]) {
2749
+ if (component !== undefined) {
2743
2750
  const entry = componentMap[component];
2744
2751
  checksToRun = Array.isArray(entry) ? entry : [entry];
2745
2752
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * V3 CLI `memory backup` command.
3
3
  *
4
- * WAL-safe snapshot of the vector-memory DB (`.swarm/memory.db`) with rotation
4
+ * WAL-safe snapshots of the active CLI and AgentDB stores with rotation
5
5
  * and optional GCS offsite. Thin surface over ../services/memory-backup.js; the
6
6
  * daemon's nightly `backup` worker calls the same service.
7
7
  */
@@ -1,39 +1,53 @@
1
1
  import { output } from '../output.js';
2
- import { backupMemoryDb, defaultMemoryDbPath } from '../services/memory-backup.js';
2
+ import { backupMemoryDb, backupProjectMemoryDbs } from '../services/memory-backup.js';
3
3
  export const backupCommand = {
4
4
  name: 'backup',
5
- description: 'Snapshot the vector-memory DB (.swarm/memory.db) — WAL-safe, rotated, optional GCS offsite',
5
+ description: 'Snapshot active project memory stores — WAL-safe, rotated, optional GCS offsite',
6
6
  options: [
7
- { name: 'db', description: 'Source DB (default: .swarm/memory.db)', type: 'string' },
7
+ { name: 'db', description: 'Source DB (default: configured CLI and AgentDB stores)', type: 'string' },
8
8
  { name: 'dir', description: 'Destination dir (default: .swarm/backups)', type: 'string' },
9
9
  { name: 'keep', description: 'Rotation — keep the newest N snapshots (default 7)', type: 'number', default: 7 },
10
10
  { name: 'gcs', description: 'Also upload the snapshot to a gs://bucket/prefix (offsite)', type: 'string' },
11
11
  { name: 'verbose', short: 'v', description: 'Verbose logging', type: 'boolean' },
12
12
  ],
13
13
  examples: [
14
- { command: 'claude-flow memory backup', description: 'Snapshot to .swarm/backups, keep last 7' },
14
+ { command: 'claude-flow memory backup', description: 'Snapshot active project stores, keep last 7' },
15
15
  { command: 'claude-flow memory backup --keep 30', description: 'Keep a month of nightly snapshots' },
16
16
  { command: 'claude-flow memory backup --gcs gs://my-bucket/ruflo-backups', description: 'Also upload offsite to GCS' },
17
17
  ],
18
18
  action: async (ctx) => {
19
- const r = await backupMemoryDb({
20
- dbPath: ctx.flags.db || defaultMemoryDbPath(ctx.cwd),
19
+ const options = {
21
20
  destDir: ctx.flags.dir,
22
21
  keep: typeof ctx.flags.keep === 'number' ? ctx.flags.keep : 7,
23
22
  gcs: ctx.flags.gcs,
24
23
  verbose: ctx.flags.verbose === true,
25
- });
24
+ };
25
+ const explicitDb = ctx.flags.db;
26
+ let r;
27
+ let receipts;
28
+ if (explicitDb) {
29
+ r = await backupMemoryDb({ ...options, dbPath: explicitDb });
30
+ receipts = [r];
31
+ }
32
+ else {
33
+ const project = await backupProjectMemoryDbs(ctx.cwd, options);
34
+ r = project;
35
+ receipts = project.backups;
36
+ }
26
37
  if (!r.backedUp) {
27
38
  // no-db is a benign "nothing to back up yet"; anything else is a real skip.
28
39
  if (r.skipped === 'no-db') {
29
- output.printWarning('No memory DB found to back up (.swarm/memory.db). Nothing to do.');
40
+ output.printWarning('No memory DB found to back up. Nothing to do.');
30
41
  return { success: true, data: r };
31
42
  }
32
43
  output.printError(`Backup skipped: ${r.skipped}`);
33
44
  return { success: false, exitCode: 1, data: r };
34
45
  }
35
46
  output.writeln();
36
- output.writeln(output.success(`Backed up → ${r.path}`));
47
+ for (const receipt of receipts) {
48
+ if (receipt.backedUp)
49
+ output.writeln(output.success(`Backed up → ${receipt.path}`));
50
+ }
37
51
  output.printList([
38
52
  `Size: ${Math.round((r.sizeBytes ?? 0) / 1024)} KB`,
39
53
  `Rotated: ${r.rotatedAway?.length ?? 0} old snapshot(s) removed`,
@@ -1,7 +1,3 @@
1
- /**
2
- * V3 CLI Memory Command
3
- * Memory operations for AgentDB integration
4
- */
5
1
  import type { Command } from '../types.js';
6
2
  export declare const memoryCommand: Command;
7
3
  export default memoryCommand;
@@ -2,6 +2,7 @@
2
2
  * V3 CLI Memory Command
3
3
  * Memory operations for AgentDB integration
4
4
  */
5
+ import { validateAppendConditions } from '../memory/append-conditions.js';
5
6
  import { output } from '../output.js';
6
7
  import { select, confirm, input } from '../prompt.js';
7
8
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
@@ -110,6 +111,10 @@ const storeCommand = {
110
111
  type: 'boolean',
111
112
  default: false
112
113
  },
114
+ { name: 'embedding', type: 'boolean', description: 'Generate an embedding (default true; --no-embedding stores structured data only)' },
115
+ { name: 'append-conditions', type: 'string', description: 'JSON predicates checked atomically with a native append-only write' },
116
+ { name: 'require-native', type: 'boolean', description: 'Refuse whole-image and in-memory fallback memory writers' },
117
+ { name: 'append-only', type: 'boolean', description: 'Immutable insert; never update or resurrect an existing key' },
113
118
  {
114
119
  name: 'upsert',
115
120
  short: 'u',
@@ -233,7 +238,7 @@ const storeCommand = {
233
238
  size: Buffer.byteLength(value, 'utf8')
234
239
  };
235
240
  output.printInfo(`Storing in ${namespace}/${key}...`);
236
- // Use direct sql.js storage with automatic embedding generation
241
+ // Use the canonical provider; embedding and native immutable append controls are explicit.
237
242
  try {
238
243
  const { storeEntry, resolveDbPath: _rdbStore } = await import('../memory/memory-initializer.js');
239
244
  const dbPath = _rdbStore(ctx.flags.path);
@@ -244,7 +249,10 @@ const storeCommand = {
244
249
  key,
245
250
  value,
246
251
  namespace,
247
- generateEmbeddingFlag: true, // Always generate embeddings for semantic search
252
+ generateEmbeddingFlag: ctx.flags.embedding !== false,
253
+ requireNative: ctx.flags.requireNative === true,
254
+ appendOnly: ctx.flags.appendOnly === true,
255
+ ...(typeof ctx.flags.appendConditions === 'string' ? { appendConditions: validateAppendConditions(JSON.parse(ctx.flags.appendConditions)) } : {}),
248
256
  tags,
249
257
  ttl,
250
258
  upsert,
@@ -86,7 +86,15 @@ const listCommand = {
86
86
  output.printError(result.error || 'Unknown error');
87
87
  return { success: false, exitCode: 1 };
88
88
  }
89
- spinner.succeed(`Registry discovered: ${result.registry.totalPlugins} plugins available`);
89
+ if (result.demo) {
90
+ // The signed registry was unavailable or failed verification (see ruvnet/ruflo#3211):
91
+ // say so instead of reporting a successful discovery over the built-in list.
92
+ spinner.stop(output.warning(`Signed plugin registry unavailable or unverified; showing the built-in list ` +
93
+ `(${result.registry.totalPlugins} plugins)`));
94
+ }
95
+ else {
96
+ spinner.succeed(`Registry discovered: ${result.registry.totalPlugins} plugins available`);
97
+ }
90
98
  output.writeln();
91
99
  // Build search options
92
100
  const searchOptions = {
@@ -165,6 +173,10 @@ const listCommand = {
165
173
  output.writeln(output.dim('(ratings: cached — cloud unavailable)'));
166
174
  }
167
175
  output.writeln(output.dim(`Source: ${result.source}${result.fromCache ? ' (cached)' : ''}`));
176
+ if (result.demo) {
177
+ output.writeln(output.warning('Not from the signed registry: download counts, ratings and trust labels are the ' +
178
+ "CLI's built-in defaults, not verified registry data."));
179
+ }
168
180
  if (result.cid) {
169
181
  output.writeln(output.dim(`Registry CID: ${result.cid.slice(0, 30)}...`));
170
182
  }
@@ -339,6 +339,18 @@ const statusCommand = {
339
339
  includeLogs: ctx.flags.logs,
340
340
  includeMetrics: true
341
341
  });
342
+ // The MCP tool answers an unknown id with status "not_found" and no other fields.
343
+ // Rendering that as a record printed "Task: undefined", "Invalid Date" and
344
+ // "undefined%" and exited 0, so scripts and agents took it as success.
345
+ if ((result.status) === 'not_found') {
346
+ if (ctx.flags.format === 'json') {
347
+ output.printJson(result);
348
+ }
349
+ else {
350
+ output.printError(`Task not found: ${taskId}`);
351
+ }
352
+ return { success: false, exitCode: 1 };
353
+ }
342
354
  if (ctx.flags.format === 'json') {
343
355
  output.printJson(result);
344
356
  return { success: true, data: result };
@@ -51,9 +51,9 @@ export function generateSettings(options) {
51
51
  pr: '🤖 Generated with [RuFlo](https://github.com/ruvnet/ruflo)',
52
52
  };
53
53
  }
54
- // Note: Claude Code expects 'model' to be a string, not an object
55
- // Additional ruflo-specific model preferences live in claudeFlow.modelPreferences below
56
- settings.model = 'claude-sonnet-5';
54
+ // #3527: deliberately no settings.model. Project settings outrank the user's
55
+ // own settings, so a pin here would silently override the model the user chose.
56
+ // Ruflo's own routing preferences live in claudeFlow.modelPreferences below.
57
57
  // Add Agent Teams configuration (experimental feature)
58
58
  settings.env = {
59
59
  // Enable Claude Code Agent Teams for multi-agent coordination