claude-flow 3.58.0 → 3.59.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 (59) hide show
  1. package/.claude/proven-config.json +1 -1
  2. package/README.md +2 -0
  3. package/node_modules/@claude-flow/codex/dist/cli.js +0 -0
  4. package/node_modules/@claude-flow/plugin-agent-federation/dist/bin.js +0 -0
  5. package/package.json +2 -1
  6. package/v3/@claude-flow/cli/README.md +62 -174
  7. package/v3/@claude-flow/cli/bin/cli.js +19 -1
  8. package/v3/@claude-flow/cli/catalog-manifest.json +5 -5
  9. package/v3/@claude-flow/cli/dist/src/commands/harness.d.ts +40 -0
  10. package/v3/@claude-flow/cli/dist/src/commands/harness.js +142 -0
  11. package/v3/@claude-flow/cli/dist/src/commands/index.js +1 -0
  12. package/v3/@claude-flow/cli/dist/src/commands/init.js +116 -0
  13. package/v3/@claude-flow/cli/dist/src/commands/memory.js +6 -1
  14. package/v3/@claude-flow/cli/dist/src/commands/status.js +2 -2
  15. package/v3/@claude-flow/cli/dist/src/index.d.ts +3 -0
  16. package/v3/@claude-flow/cli/dist/src/index.js +12 -2
  17. package/v3/@claude-flow/cli/dist/src/init/grok-generator.d.ts +96 -0
  18. package/v3/@claude-flow/cli/dist/src/init/grok-generator.js +371 -0
  19. package/v3/@claude-flow/cli/dist/src/init/grok-templates.d.ts +11 -0
  20. package/v3/@claude-flow/cli/dist/src/init/grok-templates.js +28 -0
  21. package/v3/@claude-flow/cli/dist/src/init/index.d.ts +2 -0
  22. package/v3/@claude-flow/cli/dist/src/init/index.js +2 -0
  23. package/v3/@claude-flow/cli/dist/src/mcp-client.js +4 -0
  24. package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-execute-core.js +59 -12
  25. package/v3/@claude-flow/cli/dist/src/mcp-tools/capability-brain.d.ts +1 -1
  26. package/v3/@claude-flow/cli/dist/src/mcp-tools/capability-brain.js +5 -3
  27. package/v3/@claude-flow/cli/dist/src/mcp-tools/embeddings-tools.js +11 -4
  28. package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +13 -3
  29. package/v3/@claude-flow/cli/dist/src/mcp-tools/index.d.ts +1 -0
  30. package/v3/@claude-flow/cli/dist/src/mcp-tools/index.js +2 -0
  31. package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +42 -4
  32. package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +7 -3
  33. package/v3/@claude-flow/cli/dist/src/mcp-tools/team-tools.d.ts +15 -0
  34. package/v3/@claude-flow/cli/dist/src/mcp-tools/team-tools.js +244 -0
  35. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.d.ts +19 -0
  36. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +163 -3
  37. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +4 -0
  38. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +70 -37
  39. package/v3/@claude-flow/cli/dist/src/memory/rabitq-index.d.ts +19 -0
  40. package/v3/@claude-flow/cli/dist/src/memory/rabitq-index.js +117 -1
  41. package/v3/@claude-flow/cli/dist/src/missions/schemas.d.ts +113 -113
  42. package/v3/@claude-flow/cli/dist/src/mods/command-registry/schema.d.ts +193 -193
  43. package/v3/@claude-flow/cli/dist/src/parser.js +3 -2
  44. package/v3/@claude-flow/cli/dist/src/services/live-harness.d.ts +111 -0
  45. package/v3/@claude-flow/cli/dist/src/services/live-harness.js +427 -0
  46. package/v3/@claude-flow/cli/package.json +4 -3
  47. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-architect.md +35 -0
  48. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-coder.md +34 -0
  49. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-reviewer.md +30 -0
  50. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-tester.md +26 -0
  51. package/v3/@claude-flow/cli/templates/grok/config.toml +63 -0
  52. package/v3/@claude-flow/cli/templates/grok/docs/README.md +186 -0
  53. package/v3/@claude-flow/cli/templates/grok/hooks/subagent-stop-team.json +15 -0
  54. package/v3/@claude-flow/cli/templates/grok/rules/ruflo-grok.md +132 -0
  55. package/v3/@claude-flow/cli/templates/grok/scripts/grok-subagent-stop-hook.mjs +90 -0
  56. package/v3/@claude-flow/cli/templates/grok/scripts/grok-team-bus.mjs +525 -0
  57. package/v3/@claude-flow/cli/templates/grok/scripts/grok-team-store.mjs +287 -0
  58. package/v3/@claude-flow/cli/templates/grok/scripts/host-statusline.mjs +281 -0
  59. package/v3/@claude-flow/cli/templates/grok/skills/agent-teams-grok/SKILL.md +98 -0
@@ -8,6 +8,7 @@ import * as fs from 'fs';
8
8
  import * as path from 'path';
9
9
  import { spawnSync } from 'node:child_process';
10
10
  import { executeInit, executeUpgrade, executeUpgradeWithMissing, DEFAULT_INIT_OPTIONS, MINIMAL_INIT_OPTIONS, FULL_INIT_OPTIONS, } from '../init/index.js';
11
+ import { executeGrokInit } from '../init/grok-generator.js';
11
12
  import { ENROLLMENT_SCREEN, recordEnrollmentOutcome, shouldOfferEnrollment, } from '../funnel/enrollment.js';
12
13
  import { commandExists } from '../services/harness-hosts.js';
13
14
  /**
@@ -361,6 +362,90 @@ async function maybeInstallSkillsSh(ctx) {
361
362
  // Skills.sh registration is a bonus, never a requirement — swallow everything.
362
363
  }
363
364
  }
365
+ // Grok Build host initialization (ADR-402)
366
+ async function initGrokAction(ctx, options) {
367
+ const { force, statusLine, dryRun } = options;
368
+ output.writeln();
369
+ output.writeln(output.bold(dryRun ? 'Grok Build init (dry run — nothing is written)' : 'Initializing RuFlo for Grok Build'));
370
+ output.writeln();
371
+ try {
372
+ const result = executeGrokInit({
373
+ targetDir: ctx.cwd,
374
+ force,
375
+ docs: true,
376
+ statusLine,
377
+ dryRun,
378
+ });
379
+ if (!result.success) {
380
+ output.printError('Grok initialization failed');
381
+ for (const err of result.errors) {
382
+ output.printError(err);
383
+ }
384
+ return { success: false, exitCode: 1, message: 'Grok init failed' };
385
+ }
386
+ output.printBox([
387
+ `.grok/config.toml — project MCP (ruflo) + permissions`,
388
+ `.grok/rules/ruflo-grok.md — host doctrine / tool map`,
389
+ `.grok/agents/ — ruflo-architect/coder/tester/reviewer`,
390
+ `.grok/skills/ — agent-teams-grok`,
391
+ `.grok/hooks/ — SubagentStop advances the team plan`,
392
+ `scripts/grok-team-bus.mjs (+ grok-team-store.mjs) — ADR-402 team bus CLI`,
393
+ `scripts/host-statusline.mjs — "what is loaded" row`,
394
+ `docs/grok/README.md — operator guide`,
395
+ ].join('\n'), 'Grok Build Integration (ADR-402)');
396
+ output.writeln();
397
+ const verb = dryRun ? 'Would write' : 'Wrote';
398
+ output.writeln(output.bold(`${verb} (${result.filesCreated.length}):`));
399
+ output.printList(result.filesCreated.map((f) => (path.relative(ctx.cwd, f).startsWith('..') ? f : path.relative(ctx.cwd, f))));
400
+ if (result.filesSkipped.length > 0) {
401
+ output.printInfo(`Skipped ${result.filesSkipped.length} existing file(s)${force ? '' : ' — use --force to overwrite'}`);
402
+ }
403
+ output.writeln();
404
+ const mcp = result.mcp;
405
+ output.printInfo(mcp.source === 'published'
406
+ ? `MCP server pinned to ruflo@${mcp.version} (the release that ships the team_* tools)`
407
+ : `MCP server points at this checkout: ${mcp.args[0]} — rebuild it before use, and re-run init from a published release before committing .grok/config.toml`);
408
+ const uc = result.userConfig;
409
+ if (uc.action === 'not-requested' || uc.action === 'snippet') {
410
+ output.writeln();
411
+ output.writeln(uc.action === 'snippet'
412
+ ? output.bold(`Did not change ${uc.path}: ${uc.reason}`)
413
+ : output.bold('Optional status row (Grok reads it only from your user config):'));
414
+ output.writeln(output.dim(` Add this to ${uc.path}, or re-run with --grok-statusline to have init merge it`));
415
+ output.writeln(output.dim(` (that also installs the script it runs under ~/.grok/ruflo/):`));
416
+ output.writeln(uc.snippet.trimEnd().split('\n').map((l) => ` ${l}`).join('\n'));
417
+ }
418
+ else if (uc.action === 'already-set') {
419
+ output.printInfo(uc.reason || `${uc.path} already has the Ruflo status row; refreshed the script it runs`);
420
+ }
421
+ output.writeln();
422
+ output.writeln(output.bold('Next steps:'));
423
+ output.printList([
424
+ 'Trust this folder in Grok (/hooks-trust or grok --trust) so MCP, hooks, skills, and rules load together',
425
+ 'Restart Grok so .grok/config.toml is applied',
426
+ 'Read docs/grok/README.md — spawn contract checked on Grok Build 1.0.41',
427
+ 'Verify: grok mcp list && grok mcp doctor ruflo',
428
+ 'Optional: npx ruvnet-brain@latest then enable ruvnet-brain in .grok/config.toml',
429
+ 'Teams: team_create / team_spawn MCP tools (or node scripts/grok-team-bus.mjs)',
430
+ ]);
431
+ output.writeln();
432
+ return {
433
+ success: true,
434
+ data: {
435
+ adapter: 'grok',
436
+ dryRun,
437
+ filesCreated: result.filesCreated,
438
+ filesSkipped: result.filesSkipped,
439
+ mcp: result.mcp,
440
+ userConfig: { action: uc.action, path: uc.path },
441
+ },
442
+ };
443
+ }
444
+ catch (e) {
445
+ output.printError(`Grok initialization failed: ${e.message}`);
446
+ return { success: false, exitCode: 1, message: e.message };
447
+ }
448
+ }
364
449
  // Codex initialization action
365
450
  async function initCodexAction(ctx, options) {
366
451
  const { force, minimal, full, dualMode } = options;
@@ -848,6 +933,15 @@ const initAction = async (ctx) => {
848
933
  const full = ctx.flags.full;
849
934
  const codexMode = ctx.flags.codex;
850
935
  const dualMode = ctx.flags.dual;
936
+ const grokMode = ctx.flags.grok;
937
+ // Grok Build host (ADR-402) — separate surface under .grok/
938
+ if (grokMode) {
939
+ return initGrokAction(ctx, {
940
+ force,
941
+ statusLine: ctx.flags.grokStatusline === true || ctx.flags['grok-statusline'] === true,
942
+ dryRun: ctx.flags.dryRun === true || ctx.flags['dry-run'] === true,
943
+ });
944
+ }
851
945
  if (codexMode && !dualMode) {
852
946
  return initCodexAction(ctx, { codexMode, dualMode: false, force, minimal, full });
853
947
  }
@@ -1598,6 +1692,24 @@ export const initCommand = {
1598
1692
  type: 'boolean',
1599
1693
  default: false,
1600
1694
  },
1695
+ {
1696
+ name: 'grok',
1697
+ description: 'Initialize for Grok Build host (creates .grok/, team bus scripts, ADR-402 surface)',
1698
+ type: 'boolean',
1699
+ default: false,
1700
+ },
1701
+ {
1702
+ name: 'grok-statusline',
1703
+ description: 'With --grok: also merge the Ruflo status row into ~/.grok/config.toml (user file; off by default)',
1704
+ type: 'boolean',
1705
+ default: false,
1706
+ },
1707
+ {
1708
+ name: 'dry-run',
1709
+ description: 'With --grok: list the files init would write, write nothing',
1710
+ type: 'boolean',
1711
+ default: false,
1712
+ },
1601
1713
  {
1602
1714
  name: 'dual',
1603
1715
  description: 'Initialize for both Claude Code and OpenAI Codex',
@@ -1647,6 +1759,10 @@ export const initCommand = {
1647
1759
  { command: 'claude-flow init upgrade --verbose', description: 'Show detailed upgrade info' },
1648
1760
  { command: 'claude-flow init --codex', description: 'Initialize for OpenAI Codex (AGENTS.md)' },
1649
1761
  { command: 'claude-flow init --codex --full', description: 'Codex init with all canonical packaged skills' },
1762
+ { command: 'claude-flow init --grok', description: 'Initialize for Grok Build (.grok/, team bus, ADR-402)' },
1763
+ { command: 'claude-flow init --grok --force', description: 'Overwrite existing Grok host files' },
1764
+ { command: 'claude-flow init --grok --dry-run', description: 'Show what init --grok would write' },
1765
+ { command: 'claude-flow init --grok --grok-statusline', description: 'Also add the Ruflo status row to ~/.grok/config.toml' },
1650
1766
  { command: 'claude-flow init --dual', description: 'Initialize for both Claude Code and Codex' },
1651
1767
  { command: 'claude-flow init --no-codex-detect', description: 'Skip auto-configuring OpenAI Codex even if it is installed' },
1652
1768
  { command: 'claude-flow init --no-skills-sh', description: 'Skip the post-init skills.sh registration' },
@@ -814,11 +814,16 @@ const listCommand = {
814
814
  const namespace = ctx.flags.namespace;
815
815
  const limit = ctx.flags.limit;
816
816
  const includeEmbedding = ctx.flags.embeddings === true && ctx.flags.format === 'json';
817
+ // Mirrors memory_list's MCP tool handling: comma-separated flag →
818
+ // non-empty string array, require entries to carry every tag (AND).
819
+ const tags = ctx.flags.tags
820
+ ? ctx.flags.tags.split(',').map(t => t.trim()).filter((t) => t.length > 0)
821
+ : undefined;
817
822
  // Use sql.js directly for consistent data access
818
823
  try {
819
824
  const { listEntries, resolveDbPath: _rdbList } = await import('../memory/memory-initializer.js');
820
825
  const dbPathList = _rdbList(ctx.flags.path);
821
- const listResult = await listEntries({ namespace, limit, offset: 0, dbPath: dbPathList, ...(includeEmbedding && { includeEmbedding: true }) });
826
+ const listResult = await listEntries({ namespace, limit, offset: 0, dbPath: dbPathList, tags, ...(includeEmbedding && { includeEmbedding: true }) });
822
827
  if (!listResult.success) {
823
828
  output.printError(`Failed to list: ${listResult.error}`);
824
829
  return { success: false, exitCode: 1 };
@@ -484,11 +484,11 @@ const tasksCommand = {
484
484
  { key: 'progress', header: 'Progress', width: 10 }
485
485
  ],
486
486
  data: result.tasks.map(t => ({
487
- id: t.id,
487
+ id: t.taskId,
488
488
  type: t.type,
489
489
  status: formatHealth(t.status),
490
490
  priority: t.priority,
491
- agent: t.agent || '-',
491
+ agent: t.assignedTo?.length ? t.assignedTo.join(', ') : '-',
492
492
  progress: `${t.progress}%`
493
493
  }))
494
494
  });
@@ -6,6 +6,9 @@
6
6
  */
7
7
  import './log-filters.js';
8
8
  export declare const VERSION: string;
9
+ /** Commands that only observe the running system and must not start or write anything. */
10
+ export declare const OBSERVE_ONLY_COMMANDS: ReadonlySet<string>;
11
+ export declare function isObserveOnlyCommand(name: string | undefined): boolean;
9
12
  export interface CLIOptions {
10
13
  name?: string;
11
14
  description?: string;
@@ -36,6 +36,11 @@ function getPackageVersion() {
36
36
  }
37
37
  }
38
38
  export const VERSION = getPackageVersion();
39
+ /** Commands that only observe the running system and must not start or write anything. */
40
+ export const OBSERVE_ONLY_COMMANDS = new Set(['harness']);
41
+ export function isObserveOnlyCommand(name) {
42
+ return name !== undefined && OBSERVE_ONLY_COMMANDS.has(name);
43
+ }
39
44
  /**
40
45
  * V3 CLI Application
41
46
  */
@@ -113,8 +118,13 @@ export class CLI {
113
118
  this.output.printDebug(`Flags: ${JSON.stringify(Object.fromEntries(Object.entries(flags).filter(([k]) => k !== '_')))}`);
114
119
  this.output.printDebug(`CWD: ${process.cwd()}`);
115
120
  }
121
+ // Observe-only commands (e.g. `harness`, run from SessionStart hooks)
122
+ // report on the running system, so they must not change it: no update
123
+ // check, no policy migration, no helper refresh, no proven-config
124
+ // adoption, no daemon autostart.
125
+ const observeOnly = isObserveOnlyCommand(commandPath[0] ?? positional[0]);
116
126
  // Run startup update check (non-blocking, silent on skip)
117
- if (!flags.noUpdate && flags.update !== false && commandPath[0] !== 'update' && !(commandPath[0] === 'doctor' && flags.json)) {
127
+ if (!flags.noUpdate && flags.update !== false && commandPath[0] !== 'update' && !(commandPath[0] === 'doctor' && flags.json) && !observeOnly) {
118
128
  this.checkForUpdatesOnStartup().catch(() => { });
119
129
  }
120
130
  // Version-stamped helper auto-refresh — propagate hook fixes to an already
@@ -123,7 +133,7 @@ export class CLI {
123
133
  // command can't exit before the copy lands; the fast path is a single
124
134
  // stamp read + string compare (sub-ms), and the copy runs at most once per
125
135
  // version bump. Best-effort + silent — never blocks or fails a command.
126
- if (commandPath[0] !== 'init' && commandPath[0] !== 'update') {
136
+ if (commandPath[0] !== 'init' && commandPath[0] !== 'update' && !observeOnly) {
127
137
  // ADR-324: existing installations acquire a versioned policy state on
128
138
  // first use. Migration is additive and starts in legacy mode, so older
129
139
  // AgentDB, MCP, hooks, and swarm workflows keep their exact behavior.
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Grok Build host init (ADR-402).
3
+ *
4
+ * Mirrors `init --codex`: writes project-scoped `.grok/` surface + team bus scripts
5
+ * so any repo can run Ruflo Agent Teams under Grok without Claude SendMessage.
6
+ *
7
+ * Writes outside the project only with `statusLine: true` (`--grok-statusline`):
8
+ * the status row lives in the user's ~/.grok/config.toml, which is parsed and
9
+ * merged with a real TOML parser, never blindly appended to.
10
+ */
11
+ import { grokTemplatesRoot } from './grok-templates.js';
12
+ export interface GrokInitOptions {
13
+ targetDir: string;
14
+ force?: boolean;
15
+ /** Also write docs/grok/README.md operator guide */
16
+ docs?: boolean;
17
+ /** Install the status row into the user's ~/.grok/config.toml (opt-in). */
18
+ statusLine?: boolean;
19
+ /** Report what would be written; write nothing. */
20
+ dryRun?: boolean;
21
+ /** Home directory for the user-level status row (tests). */
22
+ homeDir?: string;
23
+ }
24
+ export type GrokUserConfigAction = 'not-requested' | 'created' | 'merged' | 'already-set' | 'snippet' | 'would-write';
25
+ export interface GrokUserConfigResult {
26
+ action: GrokUserConfigAction;
27
+ /** ~/.grok/config.toml */
28
+ path: string;
29
+ /** TOML to paste when init did not write it */
30
+ snippet: string;
31
+ reason?: string;
32
+ }
33
+ export interface GrokMcpLaunch {
34
+ command: string;
35
+ args: string[];
36
+ /** published: pinned to this CLI's npm version; checkout: this local build */
37
+ source: 'published' | 'checkout';
38
+ version: string;
39
+ }
40
+ export interface GrokInitResult {
41
+ success: boolean;
42
+ dryRun: boolean;
43
+ /** Files written (or, in a dry run, that would be written) */
44
+ filesCreated: string[];
45
+ filesSkipped: string[];
46
+ errors: string[];
47
+ mcp: GrokMcpLaunch;
48
+ userConfig: GrokUserConfigResult;
49
+ }
50
+ export { grokTemplatesRoot };
51
+ /**
52
+ * How the project .grok/config.toml starts the Ruflo MCP server.
53
+ *
54
+ * The team_* tools ship in the same release as `init --grok`, so the server is
55
+ * pinned to the version that is running this init — never `@latest`, which can
56
+ * be an older release without them. Running from a source checkout (not under
57
+ * node_modules) points at that checkout's CLI, since its version may not be
58
+ * published yet.
59
+ */
60
+ export declare function rufloMcpLaunch(root?: string): GrokMcpLaunch;
61
+ /**
62
+ * Fill the template placeholders. Every inserted value is escaped as a TOML
63
+ * string, so a Windows path such as C:\Users\x stays valid TOML.
64
+ */
65
+ export declare function materializeGrokConfig(template: string, launch: GrokMcpLaunch, home: string): string;
66
+ /** Where the opt-in status row script is installed: a stable absolute path. */
67
+ export declare function grokStatusScriptPath(home: string): string;
68
+ /** `node "<abs path>"` — no shell builtins, and never a repo-relative script. */
69
+ export declare function grokStatusLineCommand(home: string): string;
70
+ export declare function grokStatusLineSnippet(home: string): string;
71
+ type MergeOutcome = {
72
+ kind: 'write';
73
+ text: string;
74
+ } | {
75
+ kind: 'already-set';
76
+ ours: boolean;
77
+ } | {
78
+ kind: 'unsafe';
79
+ reason: string;
80
+ };
81
+ /**
82
+ * Add the status row to an existing user config without disturbing it.
83
+ *
84
+ * Any existing `ui.status_line` — header, `[ ui.status_line ]`,
85
+ * `[ui."status_line"]`, dotted keys, or an inline table — is detected by
86
+ * parsing, and left alone. Otherwise the block is appended and the result is
87
+ * re-parsed: it is written only if it parses, carries exactly our status row,
88
+ * and every other value is unchanged. Anything else (unparseable file, `ui`
89
+ * as an inline table, …) falls back to printing the snippet.
90
+ */
91
+ export declare function mergeGrokStatusLine(existing: string, home: string): MergeOutcome;
92
+ /**
93
+ * Initialize Grok host surface in targetDir.
94
+ */
95
+ export declare function executeGrokInit(options: GrokInitOptions): GrokInitResult;
96
+ //# sourceMappingURL=grok-generator.d.ts.map