claude-flow 3.58.1 → 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 (57) 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/index.d.ts +1 -0
  29. package/v3/@claude-flow/cli/dist/src/mcp-tools/index.js +2 -0
  30. package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +42 -4
  31. package/v3/@claude-flow/cli/dist/src/mcp-tools/task-tools.js +7 -3
  32. package/v3/@claude-flow/cli/dist/src/mcp-tools/team-tools.d.ts +15 -0
  33. package/v3/@claude-flow/cli/dist/src/mcp-tools/team-tools.js +244 -0
  34. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.d.ts +19 -0
  35. package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +163 -3
  36. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +4 -0
  37. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +70 -37
  38. package/v3/@claude-flow/cli/dist/src/memory/rabitq-index.d.ts +19 -0
  39. package/v3/@claude-flow/cli/dist/src/memory/rabitq-index.js +117 -1
  40. package/v3/@claude-flow/cli/dist/src/missions/schemas.d.ts +113 -113
  41. package/v3/@claude-flow/cli/dist/src/mods/command-registry/schema.d.ts +193 -193
  42. package/v3/@claude-flow/cli/dist/src/services/live-harness.d.ts +111 -0
  43. package/v3/@claude-flow/cli/dist/src/services/live-harness.js +427 -0
  44. package/v3/@claude-flow/cli/package.json +4 -3
  45. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-architect.md +35 -0
  46. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-coder.md +34 -0
  47. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-reviewer.md +30 -0
  48. package/v3/@claude-flow/cli/templates/grok/agents/ruflo-tester.md +26 -0
  49. package/v3/@claude-flow/cli/templates/grok/config.toml +63 -0
  50. package/v3/@claude-flow/cli/templates/grok/docs/README.md +186 -0
  51. package/v3/@claude-flow/cli/templates/grok/hooks/subagent-stop-team.json +15 -0
  52. package/v3/@claude-flow/cli/templates/grok/rules/ruflo-grok.md +132 -0
  53. package/v3/@claude-flow/cli/templates/grok/scripts/grok-subagent-stop-hook.mjs +90 -0
  54. package/v3/@claude-flow/cli/templates/grok/scripts/grok-team-bus.mjs +525 -0
  55. package/v3/@claude-flow/cli/templates/grok/scripts/grok-team-store.mjs +287 -0
  56. package/v3/@claude-flow/cli/templates/grok/scripts/host-statusline.mjs +281 -0
  57. package/v3/@claude-flow/cli/templates/grok/skills/agent-teams-grok/SKILL.md +98 -0
@@ -818,6 +818,11 @@ export const memoryTools = [
818
818
  type: 'object',
819
819
  properties: {
820
820
  namespace: { type: 'string', description: 'Filter by namespace' },
821
+ tags: {
822
+ type: 'array',
823
+ items: { type: 'string' },
824
+ description: 'Require entries to include all of these tags (AND). Matches the description claim "optionally filtered by namespace/tags".',
825
+ },
821
826
  limit: { type: 'number', description: 'Maximum results (default: 50)' },
822
827
  offset: { type: 'number', description: 'Offset for pagination (default: 0)' },
823
828
  },
@@ -826,6 +831,9 @@ export const memoryTools = [
826
831
  await ensureInitialized();
827
832
  const { listEntries } = await getMemoryFunctions();
828
833
  const namespace = input.namespace;
834
+ const tags = Array.isArray(input.tags)
835
+ ? input.tags.filter((t) => typeof t === 'string' && t.length > 0)
836
+ : undefined;
829
837
  const limit = input.limit || 50;
830
838
  const offset = input.offset || 0;
831
839
  if (namespace) {
@@ -836,12 +844,14 @@ export const memoryTools = [
836
844
  try {
837
845
  const result = await listEntries({
838
846
  namespace,
847
+ tags,
839
848
  limit,
840
849
  offset,
841
850
  });
842
851
  const entries = result.entries.map(e => ({
843
852
  key: e.key,
844
853
  namespace: e.namespace,
854
+ tags: e.tags ?? [],
845
855
  storedAt: e.createdAt,
846
856
  updatedAt: e.updatedAt,
847
857
  accessCount: e.accessCount,
@@ -1639,7 +1649,9 @@ export const memoryTools = [
1639
1649
  }
1640
1650
  const all = { entries: [...merged.values()] };
1641
1651
  const payload = {
1642
- schema: 'ruflo-memory-export/v1',
1652
+ // ruflo-memory-export/v1.1: tags round-trip with export/import.
1653
+ // v1 importers ignore unknown fields; v1.1 importers restore tags.
1654
+ schema: 'ruflo-memory-export/v1.1',
1643
1655
  exportedAt: new Date().toISOString(),
1644
1656
  namespace: namespace ?? null,
1645
1657
  count: all.entries.length,
@@ -1650,6 +1662,8 @@ export const memoryTools = [
1650
1662
  // never-populated alias. Fall back to null only if content is
1651
1663
  // missing for backward-compat with the schema.
1652
1664
  value: typeof e.content === 'string' ? e.content : (e.value ?? null),
1665
+ // Preserve tags so memory_import is lossless for tag sets.
1666
+ tags: Array.isArray(e.tags) ? e.tags : [],
1653
1667
  createdAt: e.createdAt, updatedAt: e.updatedAt, accessCount: e.accessCount, hasEmbedding: e.hasEmbedding, size: e.size,
1654
1668
  })),
1655
1669
  };
@@ -1674,8 +1688,9 @@ export const memoryTools = [
1674
1688
  {
1675
1689
  // #1916: `ruflo memory import <file>` referenced an unregistered tool.
1676
1690
  // Reads a ruflo-memory-export JSON and re-stores each entry.
1691
+ // Honour `tags` on each entry (export v1.1+; ignored if absent).
1677
1692
  name: 'memory_import',
1678
- description: 'Import memory entries from a JSON export file (produced by memory_export) into .swarm/memory.db, re-embedding values. Use when native Read is wrong because the data must be re-stored as memory rows (with new embeddings), not just read. For importing Claude Code\'s own memory files use memory_import_claude. Pair with memory_export on the source.',
1693
+ description: 'Import memory entries from a JSON export file (produced by memory_export) into .swarm/memory.db, re-embedding values. Preserves tags when present in the export (ruflo-memory-export/v1.1+). Use when native Read is wrong because the data must be re-stored as memory rows (with new embeddings), not just read. For importing Claude Code\'s own memory files use memory_import_claude. Pair with memory_export on the source.',
1679
1694
  category: 'memory',
1680
1695
  inputSchema: {
1681
1696
  type: 'object',
@@ -1735,6 +1750,7 @@ export const memoryTools = [
1735
1750
  let imported = 0;
1736
1751
  let skipped = 0;
1737
1752
  let failed = 0;
1753
+ let withTags = 0;
1738
1754
  const errors = [];
1739
1755
  for (const e of entries) {
1740
1756
  if (!e || typeof e.key !== 'string') {
@@ -1742,11 +1758,33 @@ export const memoryTools = [
1742
1758
  continue;
1743
1759
  }
1744
1760
  const value = typeof e.value === 'string' ? e.value : JSON.stringify(e.value ?? null);
1761
+ // Restore tags from export. Accept array or JSON/comma string
1762
+ // for robustness with hand-edited fidelity manifests.
1763
+ let tags = [];
1764
+ if (Array.isArray(e.tags)) {
1765
+ tags = e.tags.filter((t) => typeof t === 'string' && t.length > 0);
1766
+ }
1767
+ else if (typeof e.tags === 'string' && e.tags.trim()) {
1768
+ try {
1769
+ const parsed = JSON.parse(e.tags);
1770
+ if (Array.isArray(parsed)) {
1771
+ tags = parsed.filter((t) => typeof t === 'string' && t.length > 0);
1772
+ }
1773
+ else {
1774
+ tags = e.tags.split(',').map(s => s.trim()).filter(Boolean);
1775
+ }
1776
+ }
1777
+ catch {
1778
+ tags = e.tags.split(',').map(s => s.trim()).filter(Boolean);
1779
+ }
1780
+ }
1745
1781
  try {
1746
- const result = await storeEntry({ key: e.key, value, namespace: nsOverride ?? e.namespace ?? 'default', upsert: input.merge !== false, dbPath });
1782
+ const result = await storeEntry({ key: e.key, value, namespace: nsOverride ?? e.namespace ?? 'default', tags, upsert: input.merge !== false, dbPath });
1747
1783
  if (!result.success)
1748
1784
  throw new Error(result.error || 'Memory write was rejected');
1749
1785
  imported++;
1786
+ if (tags.length > 0)
1787
+ withTags++;
1750
1788
  if (result.embedding)
1751
1789
  vectors++;
1752
1790
  }
@@ -1761,7 +1799,7 @@ export const memoryTools = [
1761
1799
  error: failed > 0 ? `${failed} memory write(s) failed: ${errors.join('; ')}` : undefined,
1762
1800
  failed,
1763
1801
  inputPath,
1764
- imported: { entries: imported, vectors, patterns: 0 },
1802
+ imported: { entries: imported, vectors, patterns: 0, withTags },
1765
1803
  skipped,
1766
1804
  duration: Date.now() - t0,
1767
1805
  };
@@ -207,9 +207,11 @@ export const taskTools = [
207
207
  let tasks = Object.values(store.tasks);
208
208
  // Apply filters
209
209
  if (input.status) {
210
- // Support comma-separated status values
210
+ // Support comma-separated status values. 'all' (sent by `status tasks`) means no status filter.
211
211
  const statuses = input.status.split(',').map(s => s.trim());
212
- tasks = tasks.filter(t => statuses.includes(t.status));
212
+ if (!statuses.includes('all')) {
213
+ tasks = tasks.filter(t => statuses.includes(t.status));
214
+ }
213
215
  }
214
216
  if (input.type) {
215
217
  tasks = tasks.filter(t => t.type === input.type);
@@ -222,6 +224,8 @@ export const taskTools = [
222
224
  }
223
225
  // Sort by creation date (newest first)
224
226
  tasks.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
227
+ // Count matches before applying the limit so callers can tell when the list was truncated
228
+ const total = tasks.length;
225
229
  // Apply limit
226
230
  const limit = input.limit || 50;
227
231
  tasks = tasks.slice(0, limit);
@@ -236,7 +240,7 @@ export const taskTools = [
236
240
  assignedTo: t.assignedTo,
237
241
  createdAt: t.createdAt,
238
242
  })),
239
- total: tasks.length,
243
+ total,
240
244
  filters: {
241
245
  status: input.status,
242
246
  type: input.type,
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Host-agnostic Agent Teams MCP tools (ADR-402).
3
+ *
4
+ * Comms live in Ruflo (filesystem under .claude-flow/teams/), not host
5
+ * SendMessage. team_spawn returns a host spawn plan (Grok spawn_subagent /
6
+ * Claude Task adapter).
7
+ *
8
+ * The store itself is templates/grok/scripts/grok-team-bus.mjs — the same file
9
+ * `init --grok` copies into a project as a CLI — so the MCP tools, the CLI and
10
+ * the SubagentStop hook share one implementation (locking, per-team mailboxes,
11
+ * atomic writes). This module validates MCP input and maps errors to results.
12
+ */
13
+ import { type MCPTool } from './types.js';
14
+ export declare const teamTools: MCPTool[];
15
+ //# sourceMappingURL=team-tools.d.ts.map
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Host-agnostic Agent Teams MCP tools (ADR-402).
3
+ *
4
+ * Comms live in Ruflo (filesystem under .claude-flow/teams/), not host
5
+ * SendMessage. team_spawn returns a host spawn plan (Grok spawn_subagent /
6
+ * Claude Task adapter).
7
+ *
8
+ * The store itself is templates/grok/scripts/grok-team-bus.mjs — the same file
9
+ * `init --grok` copies into a project as a CLI — so the MCP tools, the CLI and
10
+ * the SubagentStop hook share one implementation (locking, per-team mailboxes,
11
+ * atomic writes). This module validates MCP input and maps errors to results.
12
+ */
13
+ import { join } from 'node:path';
14
+ import { pathToFileURL } from 'node:url';
15
+ import { getProjectCwd } from './types.js';
16
+ import { validateText } from './validate-input.js';
17
+ import { grokTemplatesRoot } from '../init/grok-templates.js';
18
+ let busPromise = null;
19
+ function loadBus() {
20
+ if (!busPromise) {
21
+ const file = join(grokTemplatesRoot(), 'scripts', 'grok-team-bus.mjs');
22
+ busPromise = import(pathToFileURL(file).href);
23
+ busPromise.catch(() => {
24
+ busPromise = null;
25
+ });
26
+ }
27
+ return busPromise;
28
+ }
29
+ async function run(op, opts) {
30
+ try {
31
+ const bus = await loadBus();
32
+ // Some ops (create/spawn/send) hold the team lock, which now waits via a
33
+ // non-blocking async poll rather than Atomics.wait (ADR-402 round-2
34
+ // review, N3) — always await, whether or not this particular op returns
35
+ // a promise.
36
+ return { success: true, ...(await bus[op](getProjectCwd(), opts)) };
37
+ }
38
+ catch (e) {
39
+ return { success: false, error: e.message || String(e) };
40
+ }
41
+ }
42
+ function textError(value, field, max) {
43
+ if (value === undefined || value === null)
44
+ return null;
45
+ const v = validateText(String(value), field, max);
46
+ return v.valid ? null : v.error || `Invalid ${field}`;
47
+ }
48
+ const teamProp = { type: 'string', description: 'Team id (alphanumeric, dash, underscore)' };
49
+ export const teamTools = [
50
+ {
51
+ name: 'team_create',
52
+ description: 'Create a host-agnostic Agent Team (ADR-402). State under .claude-flow/teams/<team>/. Use when native SendMessage/Task teammate bus is wrong or unavailable (Grok, Codex, multi-host). Pair with team_spawn for spawn plans and team_send/team_inbox for handoffs.',
53
+ category: 'team',
54
+ inputSchema: {
55
+ type: 'object',
56
+ properties: {
57
+ name: teamProp,
58
+ topology: {
59
+ type: 'string',
60
+ description: 'Team topology (hierarchical, mesh, star, ring)',
61
+ },
62
+ maxAgents: { type: 'number', description: 'Max members (1-50, default 8); team_spawn refuses beyond it' },
63
+ host: { type: 'string', description: 'Host label (grok, claude, codex)' },
64
+ force: { type: 'boolean', description: 'Overwrite existing team metadata (reopens a shut-down team)' },
65
+ },
66
+ required: ['name'],
67
+ },
68
+ handler: async (input) => run('createTeam', {
69
+ name: input.name,
70
+ topology: input.topology,
71
+ maxAgents: input.maxAgents,
72
+ host: input.host,
73
+ force: input.force === true,
74
+ }),
75
+ },
76
+ {
77
+ name: 'team_spawn',
78
+ description: 'Register a teammate and return a host spawn plan (Grok spawn_subagent / Claude Task adapter) — does not execute the agent. Use when native Task has no way to register a teammate into the host-agnostic team roster (ADR-402); the host lead still spawns using the returned plan. Refused once the team is shut down or has maxAgents members. Pair with team_create first.',
79
+ category: 'team',
80
+ inputSchema: {
81
+ type: 'object',
82
+ properties: {
83
+ team: teamProp,
84
+ agent: { type: 'string', description: 'Agent name' },
85
+ role: { type: 'string', description: 'Role (architect, developer, tester, reviewer, …)' },
86
+ prompt: { type: 'string', description: 'Task body embedded in spawn plan prompt' },
87
+ next: {
88
+ type: 'array',
89
+ description: 'Next agent name(s) for handoff',
90
+ items: { type: 'string' },
91
+ },
92
+ },
93
+ required: ['team', 'agent'],
94
+ },
95
+ handler: async (input) => {
96
+ const err = textError(input.prompt, 'prompt', 100_000);
97
+ if (err)
98
+ return { success: false, error: err };
99
+ return run('spawnMember', {
100
+ team: input.team,
101
+ agent: input.agent,
102
+ role: input.role,
103
+ prompt: input.prompt,
104
+ next: input.next,
105
+ });
106
+ },
107
+ },
108
+ {
109
+ name: 'team_send',
110
+ description: 'Enqueue a message to a named agent mailbox on one team (or broadcast to every member with to="*"). Use when native SendMessage is wrong because the recipient may be on a different host (Grok, Codex) with no SendMessage equivalent — the message persists under .claude-flow/teams/<team>/mailbox/ instead of an in-memory channel. Pair with team_inbox to read it. Refused once the team is shut down.',
111
+ category: 'team',
112
+ inputSchema: {
113
+ type: 'object',
114
+ properties: {
115
+ team: teamProp,
116
+ to: { type: 'string', description: 'Recipient agent name, or * to broadcast to current members' },
117
+ message: { type: 'string', description: 'Message body' },
118
+ summary: { type: 'string', description: 'Short summary' },
119
+ from: { type: 'string', description: 'Sender name (default: lead)' },
120
+ type: { type: 'string', description: 'Message type (handoff, status, …)' },
121
+ priority: { type: 'number', description: 'Integer 0-999, lower is read first (default 2)' },
122
+ },
123
+ required: ['team', 'to', 'message'],
124
+ },
125
+ handler: async (input) => {
126
+ const err = textError(input.message ?? input.content, 'message', 500_000) ||
127
+ textError(input.summary, 'summary', 1_000) ||
128
+ textError(input.type, 'type', 64);
129
+ if (err)
130
+ return { success: false, error: err };
131
+ return run('sendMessage', {
132
+ team: input.team,
133
+ to: input.to,
134
+ message: input.message ?? input.content,
135
+ summary: input.summary,
136
+ from: input.from,
137
+ type: input.type,
138
+ priority: input.priority,
139
+ });
140
+ },
141
+ },
142
+ {
143
+ name: 'team_inbox',
144
+ description: 'Drain (default) or peek one agent\'s mailbox on one team. Drained messages move to mailbox/<agent>/archive; concurrent drains never return the same message twice. Use when native SendMessage is wrong because there is no host-agnostic inbox to read from — this is the Grok/Codex-side counterpart to team_send for hosts without a live message channel.',
145
+ category: 'team',
146
+ inputSchema: {
147
+ type: 'object',
148
+ properties: {
149
+ team: teamProp,
150
+ agent: { type: 'string', description: 'Agent name whose inbox to read' },
151
+ peek: { type: 'boolean', description: 'If true, do not archive/drain messages' },
152
+ },
153
+ required: ['team', 'agent'],
154
+ },
155
+ handler: async (input) => run('readInbox', { team: input.team, agent: input.agent, peek: input.peek === true }),
156
+ },
157
+ {
158
+ name: 'team_broadcast',
159
+ description: 'Fan-out a message to all registered members of one team (alias of team_send with to="*"; refused while the team has no members). Use when native SendMessage is wrong because it can\'t reach every teammate on a non-Claude host in one call; each recipient reads back via team_inbox on its own host.',
160
+ category: 'team',
161
+ inputSchema: {
162
+ type: 'object',
163
+ properties: {
164
+ team: teamProp,
165
+ message: { type: 'string', description: 'Message body' },
166
+ summary: { type: 'string', description: 'Short summary' },
167
+ from: { type: 'string', description: 'Sender (default: lead)' },
168
+ },
169
+ required: ['team', 'message'],
170
+ },
171
+ handler: async (input) => {
172
+ const send = teamTools.find((t) => t.name === 'team_send');
173
+ if (!send)
174
+ return { success: false, error: 'team_send not registered' };
175
+ return send.handler({
176
+ team: input.team,
177
+ to: '*',
178
+ message: input.message,
179
+ summary: input.summary,
180
+ from: input.from,
181
+ type: 'broadcast',
182
+ });
183
+ },
184
+ },
185
+ {
186
+ name: 'team_plan',
187
+ description: 'Set pipeline steps for a team (ordered agents); the first step becomes ready. Use when native TodoWrite is wrong because it can\'t drive multi-host agent sequencing — this pipeline advances via team_on_stop instead of a single host\'s task list.',
188
+ category: 'team',
189
+ inputSchema: {
190
+ type: 'object',
191
+ properties: {
192
+ team: teamProp,
193
+ steps: {
194
+ type: 'array',
195
+ description: 'Ordered agent names or {id,agent} objects',
196
+ items: {},
197
+ },
198
+ },
199
+ required: ['team', 'steps'],
200
+ },
201
+ handler: async (input) => run('setPlan', { team: input.team, steps: input.steps }),
202
+ },
203
+ {
204
+ name: 'team_status',
205
+ description: 'Team members, plan progress, and pending mailbox counts for this team only. Use when native Task is wrong because it has no cross-host visibility into a team\'s roster or pipeline state — reads the same .claude-flow/teams/ state that team_plan and team_send write.',
206
+ category: 'team',
207
+ inputSchema: {
208
+ type: 'object',
209
+ properties: {
210
+ team: teamProp,
211
+ },
212
+ required: ['team'],
213
+ },
214
+ handler: async (input) => run('teamStatus', { team: input.team }),
215
+ },
216
+ {
217
+ name: 'team_on_stop',
218
+ description: 'Mark agent idle, advance the team_plan pipeline, and return the next assignment hint. Use when native Task has no cross-host equivalent to SubagentStop-driven pipeline advancement; wire this from SubagentStop / post-task hooks instead of polling team_status.',
219
+ category: 'team',
220
+ inputSchema: {
221
+ type: 'object',
222
+ properties: {
223
+ team: teamProp,
224
+ agent: { type: 'string', description: 'Agent that stopped' },
225
+ },
226
+ required: ['team', 'agent'],
227
+ },
228
+ handler: async (input) => run('onStop', { team: input.team, agent: input.agent }),
229
+ },
230
+ {
231
+ name: 'team_shutdown',
232
+ description: 'Close a team: marks it and its members shutdown, after which team_spawn, team_send, team_plan and team_on_stop refuse (team_inbox and team_status still work, to drain remaining mail). Use when native Task is wrong because it has no host-agnostic team lifecycle to close out.',
233
+ category: 'team',
234
+ inputSchema: {
235
+ type: 'object',
236
+ properties: {
237
+ team: teamProp,
238
+ },
239
+ required: ['team'],
240
+ },
241
+ handler: async (input) => run('shutdownTeam', { team: input.team }),
242
+ },
243
+ ];
244
+ //# sourceMappingURL=team-tools.js.map
@@ -144,6 +144,8 @@ export declare function bridgeListEntries(options: {
144
144
  includeEmbedding?: boolean;
145
145
  /** #4056: also return rows whose TTL has passed (with `expiresAt`). For cleanup only. */
146
146
  includeExpired?: boolean;
147
+ /** Require entries to include all of these tags (AND). */
148
+ tags?: string[];
147
149
  }): Promise<{
148
150
  success: boolean;
149
151
  entries: {
@@ -165,6 +167,8 @@ export declare function bridgeListEntries(options: {
165
167
  scale: number;
166
168
  b64: string;
167
169
  };
170
+ /** Tag set stored with the entry (empty array when none). */
171
+ tags?: string[];
168
172
  }[];
169
173
  total: number;
170
174
  error?: string;
@@ -263,6 +267,10 @@ export declare function bridgeGetVectorSearchStatus(dbPath?: string): Promise<{
263
267
  * Search AgentDB v3's embedder + SQLite entries via a full-table scan and
264
268
  * brute-force cosine similarity. NOT HNSW-accelerated — see #2922. Returns
265
269
  * null if unavailable.
270
+ *
271
+ * #4203: when a RaBitQ index is available the Hamming-scan candidate set is
272
+ * reranked exactly instead of scanning the whole table; the exhaustive loop
273
+ * below stays the fallback, so results and scores keep their meaning.
266
274
  */
267
275
  export declare function bridgeSearchBruteForceCosine(queryEmbedding: number[], options?: {
268
276
  k?: number;
@@ -650,6 +658,17 @@ export declare function bridgeGetAllEmbeddings(options?: {
650
658
  namespace: string;
651
659
  embedding: number[];
652
660
  }> | null>;
661
+ /**
662
+ * Count the embeddings `bridgeGetAllEmbeddings()` would export (#4203).
663
+ * RaBitQ's auto-build uses this as its cheap "has the corpus drifted?" probe —
664
+ * a COUNT instead of re-reading every embedding blob. With `dimensions` it
665
+ * counts only rows build() would keep, so the drift ratio compares like with
666
+ * like. Returns null if the bridge is unavailable.
667
+ */
668
+ export declare function bridgeCountEmbeddings(options?: {
669
+ dimensions?: number;
670
+ dbPath?: string;
671
+ }): Promise<number | null>;
653
672
  /**
654
673
  * Public helper for the unified learning-stats aggregator: counts of entries
655
674
  * per namespace + the top-level total. Best-effort — if the bridge isn't