@claude-flow/cli 3.33.0 → 3.35.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 (49) hide show
  1. package/.claude/.proven-config-version +1 -0
  2. package/.claude/helpers/.helpers-version +1 -1
  3. package/.claude/helpers/helpers.manifest.json +2 -2
  4. package/.claude/helpers/statusline.cjs +0 -0
  5. package/.claude/proven-config.json +42 -0
  6. package/catalog-manifest.json +2 -2
  7. package/dist/src/commands/agent.js +2 -1
  8. package/dist/src/commands/agntcy/index.d.ts +64 -0
  9. package/dist/src/commands/agntcy/index.js +64 -0
  10. package/dist/src/commands/agntcy/publish.d.ts +43 -0
  11. package/dist/src/commands/agntcy/publish.js +121 -0
  12. package/dist/src/commands/agntcy/runtime.d.ts +90 -0
  13. package/dist/src/commands/agntcy/runtime.js +115 -0
  14. package/dist/src/commands/agntcy/swarm-join.d.ts +28 -0
  15. package/dist/src/commands/agntcy/swarm-join.js +85 -0
  16. package/dist/src/commands/agntcy/transport.d.ts +24 -0
  17. package/dist/src/commands/agntcy/transport.js +95 -0
  18. package/dist/src/commands/daemon.js +12 -7
  19. package/dist/src/commands/doctor.js +72 -1
  20. package/dist/src/commands/index.d.ts +1 -0
  21. package/dist/src/commands/index.js +5 -0
  22. package/dist/src/commands/metaharness.js +37 -2
  23. package/dist/src/commands/swarm.js +2 -1
  24. package/dist/src/log-filters.d.ts +3 -3
  25. package/dist/src/mcp-tools/metaharness-tools.js +35 -2
  26. package/dist/src/memory/memory-bridge.d.ts +25 -0
  27. package/dist/src/memory/memory-bridge.js +61 -8
  28. package/dist/src/memory/memory-initializer.d.ts +9 -3
  29. package/dist/src/memory/memory-initializer.js +344 -277
  30. package/dist/src/services/daemon-autostart.d.ts +31 -3
  31. package/dist/src/services/daemon-autostart.js +45 -3
  32. package/dist/src/services/distill-oracle.d.ts +1 -1
  33. package/dist/src/services/distill-oracle.js +2 -2
  34. package/dist/src/services/evolve-proof.d.ts +40 -1
  35. package/dist/src/services/evolve-proof.js +76 -14
  36. package/dist/src/services/flywheel-receipt.d.ts +15 -0
  37. package/dist/src/services/flywheel-receipt.js +22 -0
  38. package/dist/src/services/flywheel-sequential-evidence.d.ts +102 -0
  39. package/dist/src/services/flywheel-sequential-evidence.js +148 -0
  40. package/dist/src/services/flywheel-transaction.d.ts +71 -0
  41. package/dist/src/services/flywheel-transaction.js +121 -0
  42. package/dist/src/services/harness-flywheel-generations.d.ts +14 -0
  43. package/dist/src/services/harness-flywheel-generations.js +76 -4
  44. package/dist/src/services/harness-flywheel.d.ts +13 -0
  45. package/dist/src/services/harness-flywheel.js +31 -1
  46. package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
  47. package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
  48. package/package.json +5 -9
  49. package/plugins/ruflo-metaharness/scripts/smoke.sh +4 -2
@@ -0,0 +1,85 @@
1
+ /**
2
+ * V3 CLI `ruflo swarm join <namespace>` — ADR-380 §2.
3
+ *
4
+ * Joins a SLIM group-membership channel scoped to a Cognitum tenant/project
5
+ * namespace (e.g. `cognitum/research/security`). This is an AGNTCY/SLIM
6
+ * concept layered on top of — never a replacement for — this repo's own
7
+ * `swarm_init`/`hive-mind_*` MCP-tool coordination, which remains the
8
+ * default for single-host swarms per ADR-380 §2.
9
+ *
10
+ * NOT WIRED INTO THE MAIN CLI ROUTER YET. This file is exported for a
11
+ * later integration pass to attach as a new subcommand of the existing
12
+ * `swarm` command (`v3/@claude-flow/cli/src/commands/swarm.ts`).
13
+ */
14
+ import { output } from '../../output.js';
15
+ import { AGNTCY_NOT_CONFIGURED_MESSAGE, AGNTCY_PACKAGE_NAME, detectAgntcyRuntime, } from './runtime.js';
16
+ /**
17
+ * SLIM group-membership namespaces are slash-delimited (e.g.
18
+ * `cognitum/research/security`), matching the ADR-380 §2 example. Validate
19
+ * the shape locally — deterministic, no SDK required — before ever
20
+ * attempting a network join.
21
+ */
22
+ export function validateNamespace(namespace) {
23
+ if (!namespace || namespace.trim().length === 0) {
24
+ return { valid: false, error: 'namespace must be a non-empty string' };
25
+ }
26
+ // Deliberately NOT filtering empty segments — a leading/trailing/double
27
+ // slash (e.g. "cognitum//security") is a malformed namespace, not a
28
+ // cosmetic one, and should be rejected rather than silently repaired.
29
+ const segments = namespace.split('/');
30
+ if (segments.length === 0) {
31
+ return { valid: false, error: 'namespace must contain at least one segment' };
32
+ }
33
+ const validSegment = /^[a-zA-Z0-9_-]+$/;
34
+ const bad = segments.find((s) => !validSegment.test(s));
35
+ if (bad !== undefined) {
36
+ return { valid: false, error: `invalid namespace segment "${bad}" — only [a-zA-Z0-9_-] allowed per segment` };
37
+ }
38
+ return { valid: true };
39
+ }
40
+ const joinCommand = {
41
+ name: 'join',
42
+ description: 'Join a SLIM group-membership channel scoped to a namespace (ADR-380 §2)',
43
+ examples: [
44
+ { command: 'ruflo swarm join cognitum/research/security', description: 'Join the SLIM group-membership channel for a tenant namespace' },
45
+ ],
46
+ action: async (ctx) => {
47
+ const namespace = (ctx.args[0] || ctx.flags.namespace || '').trim();
48
+ if (!namespace) {
49
+ output.printError('Namespace is required. Usage: ruflo swarm join <namespace> (e.g. cognitum/research/security)');
50
+ return { success: false, exitCode: 1 };
51
+ }
52
+ const nsCheck = validateNamespace(namespace);
53
+ if (!nsCheck.valid) {
54
+ output.printError(`Invalid namespace "${namespace}": ${nsCheck.error}`);
55
+ return { success: false, exitCode: 1 };
56
+ }
57
+ const status = await detectAgntcyRuntime();
58
+ if (!status.configured) {
59
+ output.printInfo(AGNTCY_NOT_CONFIGURED_MESSAGE);
60
+ output.printInfo(`Namespace "${namespace}" was not joined via SLIM. Local swarm/hive-mind coordination ` +
61
+ '(swarm_init / hive-mind_* MCP tools) remains available and unaffected.');
62
+ return {
63
+ success: true,
64
+ data: { joined: false, namespace, configured: false, reason: status.reason },
65
+ };
66
+ }
67
+ try {
68
+ const mod = (await import(AGNTCY_PACKAGE_NAME));
69
+ if (typeof mod.joinGroup !== 'function') {
70
+ throw new Error(`"${AGNTCY_PACKAGE_NAME}" is installed but does not export joinGroup()`);
71
+ }
72
+ const result = await mod.joinGroup({ endpoint: status.endpoint, namespace });
73
+ output.printSuccess(`Joined SLIM group "${namespace}"${typeof result?.members === 'number' ? ` (${result.members} members)` : ''}.`);
74
+ return { success: true, data: { joined: true, namespace, members: result?.members } };
75
+ }
76
+ catch (error) {
77
+ const message = error instanceof Error ? error.message : String(error);
78
+ output.printError(`SLIM group join failed: ${message}`);
79
+ return { success: true, data: { joined: false, namespace, error: message } };
80
+ }
81
+ },
82
+ };
83
+ export { joinCommand as swarmJoinCommand };
84
+ export default joinCommand;
85
+ //# sourceMappingURL=swarm-join.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * V3 CLI `ruflo transport use slim` — ADR-380 §2.
3
+ *
4
+ * Switches the active swarm/hive-mind coordination transport from today's
5
+ * in-process/local-hooks routing to SLIM (secure messaging for MCP/A2A,
6
+ * hierarchical routing, group membership, MLS encryption) for agents
7
+ * coordinating across hosts or across a tenant boundary.
8
+ *
9
+ * Local transport stays the default. This command is a NO-OP on the local
10
+ * path unless an operator has both set {@link AGNTCY_ENDPOINT_ENV} AND
11
+ * installed the (not-yet-published) optional runtime package — see
12
+ * runtime.ts for the full graceful-degradation contract.
13
+ *
14
+ * NOT WIRED INTO THE MAIN CLI ROUTER YET. This file is exported for a
15
+ * later integration pass to attach as a new top-level `transport` command
16
+ * (or a subcommand of one, per the open question in ADR-380 §"Open
17
+ * Questions" about per-swarm vs. global scope).
18
+ */
19
+ import type { Command } from '../../types.js';
20
+ declare const useCommand: Command;
21
+ export declare const transportCommand: Command;
22
+ export { useCommand };
23
+ export default transportCommand;
24
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1,95 @@
1
+ /**
2
+ * V3 CLI `ruflo transport use slim` — ADR-380 §2.
3
+ *
4
+ * Switches the active swarm/hive-mind coordination transport from today's
5
+ * in-process/local-hooks routing to SLIM (secure messaging for MCP/A2A,
6
+ * hierarchical routing, group membership, MLS encryption) for agents
7
+ * coordinating across hosts or across a tenant boundary.
8
+ *
9
+ * Local transport stays the default. This command is a NO-OP on the local
10
+ * path unless an operator has both set {@link AGNTCY_ENDPOINT_ENV} AND
11
+ * installed the (not-yet-published) optional runtime package — see
12
+ * runtime.ts for the full graceful-degradation contract.
13
+ *
14
+ * NOT WIRED INTO THE MAIN CLI ROUTER YET. This file is exported for a
15
+ * later integration pass to attach as a new top-level `transport` command
16
+ * (or a subcommand of one, per the open question in ADR-380 §"Open
17
+ * Questions" about per-swarm vs. global scope).
18
+ */
19
+ import { output } from '../../output.js';
20
+ import { AGNTCY_NOT_CONFIGURED_MESSAGE, AGNTCY_PACKAGE_NAME, detectAgntcyRuntime, } from './runtime.js';
21
+ /** Transport names this command currently recognizes. Only 'slim' per ADR-380 §2. */
22
+ const SUPPORTED_TRANSPORTS = new Set(['slim']);
23
+ const useCommand = {
24
+ name: 'use',
25
+ description: 'Switch the active swarm/hive-mind transport (e.g. slim) — ADR-380 §2',
26
+ examples: [
27
+ { command: 'ruflo transport use slim', description: 'Switch coordination transport to SLIM (opt-in, degrades to local)' },
28
+ ],
29
+ action: async (ctx) => {
30
+ const requested = (ctx.args[0] || ctx.flags.transport || '').trim().toLowerCase();
31
+ if (!requested) {
32
+ output.printError('Transport name required. Usage: ruflo transport use <name> (e.g. slim)');
33
+ return { success: false, exitCode: 1 };
34
+ }
35
+ if (!SUPPORTED_TRANSPORTS.has(requested)) {
36
+ output.printError(`Unknown transport "${requested}". Supported: ${Array.from(SUPPORTED_TRANSPORTS).join(', ')}.`);
37
+ output.printInfo('Local transport remains the default and needs no explicit "use".');
38
+ return { success: false, exitCode: 1 };
39
+ }
40
+ const status = await detectAgntcyRuntime();
41
+ if (!status.configured) {
42
+ output.printInfo(AGNTCY_NOT_CONFIGURED_MESSAGE);
43
+ output.printInfo('Active transport remains: local (in-process hooks routing).');
44
+ return {
45
+ success: true,
46
+ data: { transport: 'local', requested, configured: false, reason: status.reason },
47
+ };
48
+ }
49
+ // Reachable only once the optional package is actually installed AND
50
+ // an endpoint is configured — not possible today (package unpublished).
51
+ try {
52
+ const mod = (await import(AGNTCY_PACKAGE_NAME));
53
+ if (typeof mod.createSlimTransport !== 'function') {
54
+ throw new Error(`"${AGNTCY_PACKAGE_NAME}" is installed but does not export createSlimTransport()`);
55
+ }
56
+ await mod.createSlimTransport({ endpoint: status.endpoint });
57
+ output.printSuccess(`Active transport switched to: slim (${status.endpoint})`);
58
+ return { success: true, data: { transport: 'slim', endpoint: status.endpoint, configured: true } };
59
+ }
60
+ catch (error) {
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ output.printError(`Failed to activate SLIM transport: ${message}`);
63
+ output.printInfo('Falling back to local transport.');
64
+ return { success: true, data: { transport: 'local', requested, configured: false, error: message } };
65
+ }
66
+ },
67
+ };
68
+ export const transportCommand = {
69
+ name: 'transport',
70
+ description: 'Manage the active swarm/hive-mind coordination transport (ADR-380 §2)',
71
+ subcommands: [useCommand],
72
+ examples: [
73
+ { command: 'ruflo transport use slim', description: 'Switch coordination transport to SLIM' },
74
+ ],
75
+ action: async () => {
76
+ output.writeln();
77
+ output.writeln(output.bold('AGNTCY/SLIM Transport'));
78
+ output.writeln(output.dim('='.repeat(60)));
79
+ output.writeln();
80
+ output.printBox([
81
+ 'Local transport (in-process hooks routing) is the default.',
82
+ '',
83
+ 'Subcommands:',
84
+ '',
85
+ ' use <name> Switch the active transport (currently: slim)',
86
+ '',
87
+ `See ADR-380 for setup: v3/docs/adr/ADR-380-agntcy-outshift-runtime-integration.md`,
88
+ ].join('\n'), 'AGNTCY/SLIM Transport');
89
+ output.writeln();
90
+ return { success: true };
91
+ },
92
+ };
93
+ export { useCommand };
94
+ export default transportCommand;
95
+ //# sourceMappingURL=transport.js.map
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { output } from '../output.js';
6
6
  import { getDaemon, startDaemon, stopDaemon } from '../services/worker-daemon.js';
7
+ import { resolveDaemonProjectRoot } from '../services/daemon-autostart.js';
7
8
  import { fork } from 'child_process';
8
9
  import { fileURLToPath } from 'url';
9
10
  import { dirname, join, resolve } from 'path';
@@ -61,7 +62,11 @@ const startCommand = {
61
62
  }
62
63
  // #1914: a forked daemon child receives --workspace <root>; the launcher
63
64
  // and interactive invocations have no flag and fall back to cwd.
64
- const projectRoot = resolveWorkspaceFlag(ctx.flags.workspace) ?? process.cwd();
65
+ // #2877: that cwd fallback is normalized to the owning project root, so
66
+ // `daemon start` from a subdirectory contends for the SAME lock/PID file
67
+ // as one from the root instead of silently keying its own pair.
68
+ const projectRoot = resolveWorkspaceFlag(ctx.flags.workspace)
69
+ ?? resolveDaemonProjectRoot(process.cwd());
65
70
  const isDaemonProcess = process.env.CLAUDE_FLOW_DAEMON === '1';
66
71
  // Parse resource threshold overrides from CLI flags
67
72
  const config = {};
@@ -605,7 +610,7 @@ const stopCommand = {
605
610
  ],
606
611
  action: async (ctx) => {
607
612
  const quiet = ctx.flags.quiet;
608
- const projectRoot = process.cwd();
613
+ const projectRoot = resolveDaemonProjectRoot(process.cwd());
609
614
  // #2661: `stop --all` — the containment lever for daemon fanout across
610
615
  // Git worktrees. Only processes positively identified as ruflo daemons
611
616
  // (via their self-identifying argv) are touched; each receives SIGTERM
@@ -657,7 +662,7 @@ async function stopAllDaemons(quiet) {
657
662
  await stopDaemon();
658
663
  }
659
664
  catch { /* not running in-process */ }
660
- await killBackgroundDaemon(process.cwd());
665
+ await killBackgroundDaemon(resolveDaemonProjectRoot(process.cwd()));
661
666
  const daemons = await scanRunningDaemons();
662
667
  if (daemons.length === 0) {
663
668
  if (!quiet) {
@@ -1160,7 +1165,7 @@ const statusCommand = {
1160
1165
  if (ctx.flags.all) {
1161
1166
  return renderAllDaemonsStatus();
1162
1167
  }
1163
- const projectRoot = process.cwd();
1168
+ const projectRoot = resolveDaemonProjectRoot(process.cwd());
1164
1169
  try {
1165
1170
  const daemon = getDaemon(projectRoot);
1166
1171
  const status = daemon.getStatus();
@@ -1304,7 +1309,7 @@ const triggerCommand = {
1304
1309
  // #2661: an explicit `trigger --headless` is user consent for AI
1305
1310
  // execution of THIS run (still governed by the global AI budget).
1306
1311
  // Without the flag, config.json / env opt-in still applies.
1307
- const daemon = getDaemon(process.cwd(), ctx.flags.headless === true ? { aiWorkersEnabled: true } : undefined);
1312
+ const daemon = getDaemon(resolveDaemonProjectRoot(process.cwd()), ctx.flags.headless === true ? { aiWorkersEnabled: true } : undefined);
1308
1313
  const spinner = output.createSpinner({ text: `Running ${workerType} worker...`, spinner: 'dots' });
1309
1314
  spinner.start();
1310
1315
  const result = await daemon.triggerWorker(workerType);
@@ -1347,7 +1352,7 @@ const enableCommand = {
1347
1352
  return { success: false, exitCode: 1 };
1348
1353
  }
1349
1354
  try {
1350
- const daemon = getDaemon(process.cwd());
1355
+ const daemon = getDaemon(resolveDaemonProjectRoot(process.cwd()));
1351
1356
  daemon.setWorkerEnabled(workerType, !disable);
1352
1357
  output.printSuccess(`Worker ${workerType} ${disable ? 'disabled' : 'enabled'}`);
1353
1358
  return { success: true };
@@ -1402,7 +1407,7 @@ const installSupervisorCommand = {
1402
1407
  const force = ctx.flags.force === true;
1403
1408
  const load = ctx.flags.load !== false;
1404
1409
  const dryRun = ctx.flags['dry-run'] === true || ctx.flags.dryRun === true;
1405
- const projectRoot = process.cwd();
1410
+ const projectRoot = resolveDaemonProjectRoot(process.cwd());
1406
1411
  const platform = process.platform;
1407
1412
  if (platform === 'win32') {
1408
1413
  output.printError('Windows scheduled-task installer is not yet implemented.');
@@ -1766,6 +1766,76 @@ async function checkMetaharnessIntegration() {
1766
1766
  };
1767
1767
  }
1768
1768
  }
1769
+ /**
1770
+ * Dependency-contract check: every `@metaharness/*` package this CLI DECLARES
1771
+ * in its own optionalDependencies must actually resolve at runtime. Declared
1772
+ * packages are advertised integration surfaces (`ruflo metaharness evolve`,
1773
+ * flywheel receipt interop, radio coordination) — a declared-but-absent
1774
+ * package means the install dropped an optional dep (or the declaration
1775
+ * regressed to peer-only), so the advertised integration silently degrades.
1776
+ * That is a FAIL, not a warn: warn is reserved for surfaces that were never
1777
+ * advertised as installed (the `npx metaharness` umbrella path above).
1778
+ */
1779
+ async function checkMetaharnessDeclaredPackages() {
1780
+ const NAME = 'MetaHarness declared packages (ADR-150)';
1781
+ try {
1782
+ // Walk up from this module to the CLI package root (works for npx cache,
1783
+ // global install, project-local install, and monorepo dev alike).
1784
+ let root = null;
1785
+ let q = dirname(fileURLToPath(import.meta.url));
1786
+ for (let i = 0; i < 8; i++) {
1787
+ const pj = join(q, 'package.json');
1788
+ if (existsSync(pj)) {
1789
+ try {
1790
+ if (JSON.parse(readFileSync(pj, 'utf-8')).name === '@claude-flow/cli') {
1791
+ root = q;
1792
+ break;
1793
+ }
1794
+ }
1795
+ catch { /* keep walking */ }
1796
+ }
1797
+ q = dirname(q);
1798
+ }
1799
+ if (!root)
1800
+ return { name: NAME, status: 'warn', message: 'could not locate the @claude-flow/cli package root' };
1801
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8'));
1802
+ const declared = Object.keys(pkg.optionalDependencies ?? {}).filter((n) => n === 'metaharness' || n.startsWith('@metaharness/'));
1803
+ if (declared.length === 0) {
1804
+ return {
1805
+ name: NAME,
1806
+ status: 'fail',
1807
+ message: 'no @metaharness/* packages declared in optionalDependencies — the dependency contract regressed (peer-only declarations are never installed)',
1808
+ fix: 'Restore @metaharness/darwin, @metaharness/flywheel, @metaharness/radio to optionalDependencies in @claude-flow/cli',
1809
+ };
1810
+ }
1811
+ // Node resolution: nearest node_modules wins, walking upward from the CLI root.
1812
+ const resolves = (name) => {
1813
+ let d = root;
1814
+ for (let i = 0; i < 10; i++) {
1815
+ if (existsSync(join(d, 'node_modules', name, 'package.json')))
1816
+ return true;
1817
+ const parent = dirname(d);
1818
+ if (parent === d)
1819
+ break;
1820
+ d = parent;
1821
+ }
1822
+ return false;
1823
+ };
1824
+ const missing = declared.filter((n) => !resolves(n));
1825
+ if (missing.length > 0) {
1826
+ return {
1827
+ name: NAME,
1828
+ status: 'fail',
1829
+ message: `declared but not installed: ${missing.join(', ')} — advertised MetaHarness surfaces are degraded`,
1830
+ fix: 'npm install --include=optional # optional deps were skipped or pruned',
1831
+ };
1832
+ }
1833
+ return { name: NAME, status: 'pass', message: `${declared.length} declared package(s) resolve: ${declared.join(', ')}` };
1834
+ }
1835
+ catch (err) {
1836
+ return { name: NAME, status: 'warn', message: `check failed: ${err instanceof Error ? err.message : String(err)}` };
1837
+ }
1838
+ }
1769
1839
  async function checkMetaharness() {
1770
1840
  try {
1771
1841
  const version = await runCommand('npx -y metaharness@latest --version 2>&1', 15000);
@@ -2116,6 +2186,7 @@ export const doctorCommand = {
2116
2186
  checkEncryptionAtRest, // ADR-096 Phase 5
2117
2187
  checkFederationBreaker, // ADR-097 Phase 4
2118
2188
  checkMetaharness, // ADR-150 — MetaHarness upstream package
2189
+ checkMetaharnessDeclaredPackages, // dependency contract — declared optional deps must resolve
2119
2190
  checkMetaharnessIntegration, // iter 45 — ruflo-side integration layer
2120
2191
  checkFunnel, // ADR-305 — effective funnel state + deciding precedence source
2121
2192
  checkProxySponsoredConsent, // ADR-313 — Meta LLM Proxy sponsored-downtime health
@@ -2158,7 +2229,7 @@ export const doctorCommand = {
2158
2229
  'agentic-flow': checkAgenticFlow,
2159
2230
  'encryption': checkEncryptionAtRest, // ADR-096 Phase 5
2160
2231
  'federation': checkFederationBreaker, // ADR-097 Phase 4
2161
- 'metaharness': checkMetaharness, // ADR-150 — upstream package
2232
+ 'metaharness': [checkMetaharness, checkMetaharnessDeclaredPackages, checkMetaharnessIntegration], // ADR-150 — upstream + declared deps + ruflo-side
2162
2233
  'metaharness-integration': checkMetaharnessIntegration, // iter 45 — ruflo-side
2163
2234
  'funnel': checkFunnel, // ADR-305
2164
2235
  // ADR-307 — deep-dive array, same pattern as 'memory' above: the cheap
@@ -45,6 +45,7 @@ export declare function getGuidanceCommand(): Promise<Command | undefined>;
45
45
  export declare function getApplianceCommand(): Promise<Command | undefined>;
46
46
  export declare function getCleanupCommand(): Promise<Command | undefined>;
47
47
  export declare function getAutopilotCommand(): Promise<Command | undefined>;
48
+ export declare function getTransportCommand(): Promise<Command | undefined>;
48
49
  /**
49
50
  * Core commands loaded synchronously (available immediately)
50
51
  * Advanced commands loaded on-demand for faster startup
@@ -90,6 +90,10 @@ const commandLoaders = {
90
90
  spinner: () => import('./spinner.js'),
91
91
  // Ruflo entries in Claude Code's companyAnnouncements startup rotation (ADR-319)
92
92
  announcements: () => import('./announcements.js'),
93
+ // AGNTCY/Outshift runtime transport selection (ADR-324 §2) — optional,
94
+ // removable augmentation; no-ops to local transport when AGNTCY/SLIM is
95
+ // not configured (RUFLO_AGNTCY_SLIM_ENDPOINT unset).
96
+ transport: () => import('./agntcy/transport.js'),
93
97
  };
94
98
  // Cache for loaded commands
95
99
  const loadedCommands = new Map();
@@ -188,6 +192,7 @@ export async function getGuidanceCommand() { return loadCommand('guidance'); }
188
192
  export async function getApplianceCommand() { return loadCommand('appliance'); }
189
193
  export async function getCleanupCommand() { return loadCommand('cleanup'); }
190
194
  export async function getAutopilotCommand() { return loadCommand('autopilot'); }
195
+ export async function getTransportCommand() { return loadCommand('transport'); }
191
196
  /**
192
197
  * Core commands loaded synchronously (available immediately)
193
198
  * Advanced commands loaded on-demand for faster startup
@@ -39,7 +39,7 @@ import { existsSync, readFileSync } from 'fs';
39
39
  import { join, dirname, resolve } from 'path';
40
40
  import { fileURLToPath } from 'url';
41
41
  import { runFlywheelWorker } from '../services/harness-flywheel-runtime.js';
42
- import { listFlywheelReceipts, promoteFlywheelCandidate, readFlywheelTransactionState, verifyFlywheelLedger, } from '../services/flywheel-transaction.js';
42
+ import { listFlywheelReceipts, promoteFlywheelCandidate, readFlywheelTransactionState, resetSequentialEvidence, verifyFlywheelLedger, } from '../services/flywheel-transaction.js';
43
43
  import { evaluatePolicyRequest } from '../services/policy-runtime.js';
44
44
  const __dirname = dirname(fileURLToPath(import.meta.url));
45
45
  // Subcommand → plugin script filename
@@ -124,6 +124,37 @@ async function dispatchFlywheel(operation, positional, flags) {
124
124
  const state = readFlywheelTransactionState(projectRoot);
125
125
  data = { ledgerHead: state.ledgerHead, commits: state.commits };
126
126
  }
127
+ else if (operation === 'evidence-reset') {
128
+ // ADR-381 §2 — start a new evidence epoch. Same policy gate as promote:
129
+ // this reopens the family-wise alpha budget, so it is a governance action.
130
+ const reason = String(flywheelFlag(flags, 'reason', '')).trim();
131
+ if (!reason) {
132
+ data = { success: false, reason: 'evidence-reset requires --reason "<why>" — the reset audit trail records intent' };
133
+ }
134
+ else {
135
+ const policy = await evaluatePolicyRequest({
136
+ identity: { id: process.env.CLAUDE_FLOW_PRINCIPAL_ID ?? 'metaharness-local', type: 'agent', roles: ['optimizer'] },
137
+ action: {
138
+ type: 'metaharness.evidence.reset',
139
+ resource: projectRoot,
140
+ environment: 'production',
141
+ destructive: true,
142
+ },
143
+ context: {
144
+ approvalIds: String(flywheelFlag(flags, 'approvalId', '')).split(',').filter(Boolean),
145
+ },
146
+ }, projectRoot);
147
+ if (policy.enforcedOutcome !== 'allowed') {
148
+ data = { success: false, reason: `policy-${policy.enforcedOutcome}:${policy.reason}`, policyReceiptId: policy.receiptId };
149
+ }
150
+ else {
151
+ data = await resetSequentialEvidence(projectRoot, {
152
+ confirm: flywheelFlag(flags, 'confirm', false) === true,
153
+ reason,
154
+ });
155
+ }
156
+ }
157
+ }
127
158
  else if (operation === 'promote') {
128
159
  const receiptId = positional[0];
129
160
  const publicKeyPath = flywheelFlag(flags, 'publicKey');
@@ -151,6 +182,10 @@ async function dispatchFlywheel(operation, positional, flags) {
151
182
  data = await promoteFlywheelCandidate(projectRoot, receiptId, {
152
183
  confirm: flywheelFlag(flags, 'confirm', false) === true,
153
184
  trustedPublicKeys: new Set([publicKey]),
185
+ // --allow-aggregate-evidence: explicit migration escape hatch for
186
+ // pre-upgrade receipts without task-level pairedOutcomes. Default
187
+ // is strict — aggregate-only evidence is refused.
188
+ requirePairedEvidence: flywheelFlag(flags, 'allowAggregateEvidence', false) !== true,
154
189
  });
155
190
  }
156
191
  }
@@ -288,7 +323,7 @@ export const metaharnessCommand = {
288
323
  output.writeln(' redblue adversarial red/blue LLM testing (init|run|patch|attack|report)');
289
324
  output.writeln(' evolve Darwin candidate evolution');
290
325
  output.writeln(' bench create or verify a stable benchmark suite');
291
- output.writeln(' flywheel receipt loop: run | status | receipts | history | promote');
326
+ output.writeln(' flywheel receipt loop: run | status | receipts | history | promote | evidence-reset');
292
327
  output.writeln('');
293
328
  output.writeln('Each subcommand accepts --format json|table and --help.');
294
329
  output.writeln('');
@@ -5,6 +5,7 @@
5
5
  import { output } from '../output.js';
6
6
  import { select, confirm } from '../prompt.js';
7
7
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
8
+ import { swarmJoinCommand } from './agntcy/swarm-join.js';
8
9
  import * as fs from 'fs';
9
10
  import * as path from 'path';
10
11
  // Get dynamic swarm status from memory/session files
@@ -1009,7 +1010,7 @@ const pheromoneCommand = {
1009
1010
  export const swarmCommand = {
1010
1011
  name: 'swarm',
1011
1012
  description: 'Swarm coordination commands',
1012
- subcommands: [initCommand, startCommand, statusCommand, stopCommand, scaleCommand, coordinateCommand, compressMessageCommand, pheromoneCommand],
1013
+ subcommands: [initCommand, startCommand, statusCommand, stopCommand, scaleCommand, coordinateCommand, compressMessageCommand, pheromoneCommand, swarmJoinCommand],
1013
1014
  options: [],
1014
1015
  examples: [
1015
1016
  { command: 'claude-flow swarm init --v3-mode', description: 'Initialize V3 swarm' },
@@ -40,7 +40,7 @@ declare const STDERR_REDIRECT_PREFIXES: string[];
40
40
  declare const AGENTDB_MOCK_FALLBACK_DROP_PREFIXES: string[];
41
41
  declare const shouldRedirectToStderr: (msg: unknown) => boolean;
42
42
  declare const isAgentdbMockFallbackNoise: (msg: unknown) => boolean;
43
- declare const origWarn: (message?: any, ...optionalParams: any[]) => void;
44
- declare const origLog: (message?: any, ...optionalParams: any[]) => void;
45
- declare const origError: (message?: any, ...optionalParams: any[]) => void;
43
+ declare const origWarn: (...data: any[]) => void;
44
+ declare const origLog: (...data: any[]) => void;
45
+ declare const origError: (...data: any[]) => void;
46
46
  //# sourceMappingURL=log-filters.d.ts.map
@@ -53,7 +53,7 @@ import { join, dirname, resolve } from 'node:path';
53
53
  import { fileURLToPath } from 'node:url';
54
54
  import { runFlywheelWorker } from '../services/harness-flywheel-runtime.js';
55
55
  import { evaluatePolicyRequest } from '../services/policy-runtime.js';
56
- import { listFlywheelReceipts, promoteFlywheelCandidate, readFlywheelTransactionState, verifyFlywheelLedger, } from '../services/flywheel-transaction.js';
56
+ import { listFlywheelReceipts, promoteFlywheelCandidate, readFlywheelTransactionState, resetSequentialEvidence, verifyFlywheelLedger, } from '../services/flywheel-transaction.js';
57
57
  const __dirname = dirname(fileURLToPath(import.meta.url));
58
58
  /**
59
59
  * Walk up from this module to find plugins/ruflo-metaharness/scripts/.
@@ -690,7 +690,7 @@ export const metaharnessTools = [
690
690
  inputSchema: {
691
691
  type: 'object',
692
692
  properties: {
693
- operation: { type: 'string', enum: ['run', 'status', 'receipts', 'history', 'promote'], description: 'Flywheel operation', default: 'status' },
693
+ operation: { type: 'string', enum: ['run', 'status', 'receipts', 'history', 'promote', 'evidence-reset'], description: 'Flywheel operation', default: 'status' },
694
694
  projectRoot: { type: 'string', description: 'Target project root (default: active project cwd)' },
695
695
  receiptId: { type: 'string', description: 'Receipt content ID for promote' },
696
696
  sample: { type: 'number', description: 'Maximum harvested evaluation sample', default: 40 },
@@ -704,6 +704,8 @@ export const metaharnessTools = [
704
704
  anchorHash: { type: 'string', description: 'Pinned sha256 of canonical anchor tasks; requires anchorPath' },
705
705
  anchorManifestPath: { type: 'string', description: 'Project-contained anchor manifest path (default .claude/eval/flywheel-anchor.manifest.json)' },
706
706
  approvalIds: { type: 'array', items: { type: 'string' }, description: 'Scoped ADR-324 approval IDs for privileged promotion' },
707
+ allowAggregateEvidence: { type: 'boolean', description: 'Migration escape hatch: accept a pre-upgrade receipt without task-level pairedOutcomes. Default false — aggregate-only evidence is refused by the strict sequential-evidence gate.', default: false },
708
+ reason: { type: 'string', description: 'Required for evidence-reset (ADR-381): the human intent recorded in the append-only reset audit trail.' },
707
709
  },
708
710
  required: ['operation'],
709
711
  },
@@ -758,6 +760,36 @@ export const metaharnessTools = [
758
760
  });
759
761
  return { success: data.ran, data, degraded: false, exitCode: data.ran ? 0 : 1 };
760
762
  }
763
+ if (operation === 'evidence-reset') {
764
+ // ADR-381 §2 — reopens the family-wise alpha budget; same policy
765
+ // gate as promote, plus a mandatory recorded reason.
766
+ const reason = String(input.reason ?? '').trim();
767
+ if (!reason) {
768
+ return { success: false, data: { reason: 'evidence-reset requires a non-empty reason — the reset audit trail records intent' }, degraded: false, exitCode: 2 };
769
+ }
770
+ const policy = await evaluatePolicyRequest({
771
+ identity: { id: 'metaharness-mcp', type: 'agent', roles: ['optimizer'] },
772
+ action: {
773
+ type: 'metaharness.evidence.reset',
774
+ resource: projectRoot,
775
+ environment: 'production',
776
+ destructive: true,
777
+ },
778
+ context: {
779
+ approvalIds: Array.isArray(input.approvalIds) ? input.approvalIds.map(String) : undefined,
780
+ },
781
+ }, projectRoot);
782
+ if (policy.enforcedOutcome !== 'allowed') {
783
+ return {
784
+ success: false,
785
+ data: { reason: `policy-${policy.enforcedOutcome}:${policy.reason}`, policyReceiptId: policy.receiptId },
786
+ degraded: false,
787
+ exitCode: 1,
788
+ };
789
+ }
790
+ const data = await resetSequentialEvidence(projectRoot, { confirm: input.confirm === true, reason });
791
+ return { success: data.success, data, degraded: false, exitCode: data.success ? 0 : 1 };
792
+ }
761
793
  if (operation === 'promote') {
762
794
  if (!input.receiptId || !input.publicKeyPath) {
763
795
  return { success: false, data: { reason: 'receiptId and publicKeyPath are required' }, degraded: false, exitCode: 2 };
@@ -786,6 +818,7 @@ export const metaharnessTools = [
786
818
  const data = await promoteFlywheelCandidate(projectRoot, String(input.receiptId), {
787
819
  confirm: input.confirm === true,
788
820
  trustedPublicKeys: new Set([publicKey]),
821
+ requirePairedEvidence: input.allowAggregateEvidence !== true,
789
822
  });
790
823
  return { success: data.success, data, degraded: false, exitCode: data.success ? 0 : 1 };
791
824
  }
@@ -487,6 +487,14 @@ export declare function bridgeHealthCheck(dbPath?: string): Promise<{
487
487
  hits: number;
488
488
  misses: number;
489
489
  };
490
+ hierarchicalMemory?: {
491
+ controller: string;
492
+ durable: boolean;
493
+ persistence: string;
494
+ /** Real row count in the backing table — null when nothing is on disk. */
495
+ persistedRows: number | null;
496
+ fallbackFrom?: string;
497
+ };
490
498
  } | null>;
491
499
  /**
492
500
  * Store to hierarchical memory with tier.
@@ -506,6 +514,23 @@ export declare function bridgeHealthCheck(dbPath?: string): Promise<{
506
514
  * temporal fields are stored in metadata, and supersede is reported as
507
515
  * unsupported (no public update API) rather than silently dropped.
508
516
  */
517
+ /**
518
+ * Describe which store `agentdb_hierarchical-*` actually landed on and
519
+ * whether its writes survive the process (#2887).
520
+ *
521
+ * agentdb removed its `HierarchicalMemory` export at 3.0.0-alpha.17, so the
522
+ * @claude-flow/memory TieredMemoryStore fallback is the live path. It is only
523
+ * durable when it was handed a SQLite connection — callers must not report a
524
+ * volatile write as a success.
525
+ */
526
+ export declare function describeHierarchicalStore(hm: any, fallback: {
527
+ reason: string;
528
+ } | null): {
529
+ controller: string;
530
+ fallbackFrom?: string;
531
+ durable: boolean;
532
+ persistence: string;
533
+ };
509
534
  export declare function bridgeHierarchicalStore(params: {
510
535
  key: string;
511
536
  value: string;