brainclaw 1.14.0 → 1.16.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.
- package/README.md +16 -263
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli/register-capture.js +209 -0
- package/dist/cli/register-code-map.js +19 -0
- package/dist/cli/register-coordination.js +472 -0
- package/dist/cli/register-federation.js +258 -0
- package/dist/cli/register-lifecycle.js +436 -0
- package/dist/cli/register-memory-context.js +502 -0
- package/dist/cli/register-planning.js +167 -0
- package/dist/cli/register-review.js +149 -0
- package/dist/cli/shared.js +5 -0
- package/dist/cli.js +212 -2015
- package/dist/commands/dispatch-watch.js +25 -2
- package/dist/commands/harvest.js +31 -6
- package/dist/commands/mcp-catalog.js +1438 -0
- package/dist/commands/mcp-contract.js +33 -0
- package/dist/commands/mcp-presentation.js +27 -0
- package/dist/commands/mcp-read-handlers.js +72 -36
- package/dist/commands/mcp-write-admin.js +328 -0
- package/dist/commands/mcp-write-claims.js +864 -0
- package/dist/commands/mcp-write-coordination.js +1825 -0
- package/dist/commands/mcp-write-entities.js +620 -0
- package/dist/commands/mcp-write-memory.js +451 -0
- package/dist/commands/mcp-write-sequences.js +116 -0
- package/dist/commands/mcp-write-support.js +367 -0
- package/dist/commands/mcp.js +261 -5570
- package/dist/commands/update-handoff.js +28 -42
- package/dist/core/agent-capability.js +31 -14
- package/dist/core/agent-files.js +1 -1
- package/dist/core/agent-registry.js +51 -3
- package/dist/core/claims.js +18 -0
- package/dist/core/coordination.js +5 -2
- package/dist/core/cross-project.js +35 -1
- package/dist/core/dispatcher.js +34 -20
- package/dist/core/entity-operations.js +335 -12
- package/dist/core/entity-registry.js +72 -9
- package/dist/core/execution.js +28 -4
- package/dist/core/facade-schema.js +30 -4
- package/dist/core/federation-cloud.js +142 -11
- package/dist/core/federation-outbox.js +292 -0
- package/dist/core/federation-signing.js +115 -0
- package/dist/core/handoff-review.js +35 -0
- package/dist/core/io.js +6 -0
- package/dist/core/protocol-tool-policy.js +113 -0
- package/dist/core/review-loop-close.js +115 -0
- package/dist/core/schema.js +25 -2
- package/dist/core/security-detectors.js +35 -6
- package/dist/core/security.js +32 -12
- package/dist/core/worktree.js +98 -9
- package/dist/facts.js +13 -11
- package/dist/facts.json +12 -10
- package/docs/PROTOCOL.md +7 -3
- package/docs/concepts/coordinator-runbook.md +3 -0
- package/docs/concepts/dispatch-lifecycle.md +4 -4
- package/docs/concepts/loop-engine.md +3 -1
- package/docs/concepts/troubleshooting.md +1 -1
- package/docs/integrations/codex.md +3 -3
- package/docs/integrations/overview.md +1 -1
- package/docs/mcp-schema-changelog.md +153 -2
- package/docs/playbooks/orchestration.md +1 -1
- package/docs/product/entity-model-audit.md +3 -2
- package/docs/security.md +22 -1
- package/package.json +3 -1
|
@@ -0,0 +1,1438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool catalog — every tool descriptor (read + write), the published /
|
|
3
|
+
* default / uninitialized projections, the facade ordering logic, and the
|
|
4
|
+
* annotation-derived tool-name sets.
|
|
5
|
+
*
|
|
6
|
+
* Extracted from mcp.ts (pln#622 PR1). May import mcp-contract.js and the
|
|
7
|
+
* generated schemas; must not import mcp.js (assembly point) — enforced by
|
|
8
|
+
* tests/unit/mcp-dependency-direction.test.ts and the eslint
|
|
9
|
+
* no-restricted-imports guard.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { generatedSchemas } from './mcp-schemas.generated.js';
|
|
14
|
+
const SEQUENCE_ITEM_INPUT_SCHEMA = {
|
|
15
|
+
type: 'object',
|
|
16
|
+
description: 'Sequence lane item. planId is required; stepId optionally narrows dispatch/readiness to a specific plan step.',
|
|
17
|
+
properties: {
|
|
18
|
+
planId: { type: 'string', minLength: 1, description: 'Plan item ID referenced by this sequence item.' },
|
|
19
|
+
stepId: { type: 'string', minLength: 1, description: 'Optional plan step ID inside planId for step-level dispatch/readiness.' },
|
|
20
|
+
rank: { type: 'number', minimum: 1, description: 'Positive integer ordering key. Ranks must be unique within a sequence.' },
|
|
21
|
+
hard_after: {
|
|
22
|
+
type: 'array',
|
|
23
|
+
items: { type: 'string' },
|
|
24
|
+
description: 'Sequence item planId values that must complete before this item becomes ready.',
|
|
25
|
+
},
|
|
26
|
+
soft_after: {
|
|
27
|
+
type: 'array',
|
|
28
|
+
items: { type: 'string' },
|
|
29
|
+
description: 'Advisory predecessor planId values; they inform ordering but do not block readiness.',
|
|
30
|
+
},
|
|
31
|
+
lane: { type: 'string', description: 'Optional lane label used for parallel dispatch grouping and filtering.' },
|
|
32
|
+
scope_hint: { type: 'string', description: 'Optional file/path scope hint for claim and brief generation.' },
|
|
33
|
+
rationale: { type: 'string', description: 'Optional explanation for this item or dependency placement.' },
|
|
34
|
+
},
|
|
35
|
+
required: ['planId', 'rank'],
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
};
|
|
38
|
+
const { $defs: loopPhaseDefs, ...loopPhaseItemSchema } = generatedSchemas.LoopPhase;
|
|
39
|
+
const loopSlotInputItemSchema = generatedSchemas.LoopSlotInput;
|
|
40
|
+
export const MCP_READ_TOOLS = [
|
|
41
|
+
{
|
|
42
|
+
name: 'bclaw_bootstrap',
|
|
43
|
+
description: 'Derive brownfield bootstrap signals, adaptive interview prompts for CLI or IDE chat agents, and an import proposal from repository docs, manifests, native agent files, and git history.',
|
|
44
|
+
annotations: { tier: 'standard', category: 'context', headlessApproval: 'prompt' },
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: 'object',
|
|
47
|
+
properties: {
|
|
48
|
+
target: { type: 'string', description: 'Optional path or scope to tailor the bootstrap.' },
|
|
49
|
+
refresh: { type: 'boolean', description: 'Force a fresh bootstrap scan.' },
|
|
50
|
+
audience: { type: 'string', description: 'Optional interview audience filter: cli, ide_chat, or any.' },
|
|
51
|
+
interview: { type: 'boolean', description: 'Render interview text instead of the summary text.' },
|
|
52
|
+
apply: { type: 'boolean', description: 'Apply the current import proposal into canonical memory. Requires yes: true.' },
|
|
53
|
+
uninstall: { type: 'boolean', description: 'Uninstall the last bootstrap-managed import. Requires yes: true.' },
|
|
54
|
+
yes: { type: 'boolean', description: 'Explicit confirmation for apply/uninstall (mirrors the CLI --yes gate). Without it the call returns confirmation_required and makes no changes.' },
|
|
55
|
+
interviewAnswers: {
|
|
56
|
+
type: 'array',
|
|
57
|
+
description: 'Optional structured interview answers. Each answer may include question_id, response_text, response_items, response_boolean, and explicit suggestions.',
|
|
58
|
+
items: { type: 'object' },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'bclaw_release_notes',
|
|
65
|
+
description: 'Return the agent-first release notes for the latest installable Brainclaw version from the configured update source. Returns structured highlights, breaking risk, and action recommendation when available.',
|
|
66
|
+
annotations: { tier: 'standard', category: 'context', headlessApproval: 'prompt' },
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
// ── Canonical context read (Phase 3 slice 3c) ──────────────────────
|
|
74
|
+
// Unified dispatcher over the four legacy context reads.
|
|
75
|
+
// Promoted to standard tier at the v1.0 cut.
|
|
76
|
+
name: 'bclaw_context',
|
|
77
|
+
description: 'Unified context read. Dispatches by kind: memory (project memory for a path), execution (local execution env), board (full agent board), board_summary (compact counts), cross_project (linked_projects + incoming_signals only), delta (memory changes since a reference session).',
|
|
78
|
+
annotations: { tier: 'facade', category: 'context', headlessApproval: 'auto' },
|
|
79
|
+
inputSchema: {
|
|
80
|
+
type: 'object',
|
|
81
|
+
properties: {
|
|
82
|
+
kind: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
enum: ['memory', 'execution', 'board', 'board_summary', 'cross_project', 'delta'],
|
|
85
|
+
description: 'memory = project memory context; execution = local env/tooling; board = full agent board; board_summary = lightweight counts; cross_project = linked_projects + incoming_signals only; delta = memory changes since `since`.',
|
|
86
|
+
},
|
|
87
|
+
since: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
description: 'For kind=delta: a session_id (sess_...) used as the reference point. Future: also accept ISO timestamp or handoff_id.',
|
|
90
|
+
},
|
|
91
|
+
path: { type: 'string', description: 'kind=memory: file path or glob to filter memory by.' },
|
|
92
|
+
agent: { type: 'string', description: 'Agent name (memory/board kinds).' },
|
|
93
|
+
host: { type: 'string', description: 'Host identifier (memory kind).' },
|
|
94
|
+
allHosts: { type: 'boolean', description: 'Include machine-local runtime from all hosts (memory kind).' },
|
|
95
|
+
profile: { type: 'string', description: 'Memory profile: dev, dense, compact, copilot, quick, briefing, openclaw, ops, research.' },
|
|
96
|
+
includePending: { type: 'boolean', description: 'Include pending candidates (memory kind).' },
|
|
97
|
+
maxItems: { type: 'number', description: 'Max ranked items (memory kind).' },
|
|
98
|
+
maxChars: { type: 'number', description: 'Approximate character budget (memory kind).' },
|
|
99
|
+
digest: { type: 'boolean', description: 'Include deterministic digest (memory kind).' },
|
|
100
|
+
bootstrap: { type: 'boolean', description: 'Enable brownfield bootstrap fallback (memory kind).' },
|
|
101
|
+
refreshBootstrap: { type: 'boolean', description: 'Force fresh bootstrap scan (memory kind).' },
|
|
102
|
+
format: { type: 'string', description: 'Output format (memory kind): markdown, json, template.' },
|
|
103
|
+
explain: { type: 'boolean', description: 'Include ranking reasons (memory kind, markdown format).' },
|
|
104
|
+
compactTemplate: { type: 'boolean', description: 'Use compact template (memory kind, format=template).' },
|
|
105
|
+
includeAgentTooling: { type: 'boolean', description: 'Include agent tooling signals (execution kind).' },
|
|
106
|
+
project: { type: 'string', description: 'Optional: name of a linked project to read context from. Defaults to the current project. Accepts cross_project_links and workspace store-chain children.' },
|
|
107
|
+
budget_tokens: { type: 'number', description: 'Approximate token budget for the payload (~4 chars/token). memory kind: relevance-ranked item fill; board kind: arrays bounded by size.' },
|
|
108
|
+
},
|
|
109
|
+
required: ['kind'],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'bclaw_search',
|
|
114
|
+
description: 'Full-text search across all memory items (decisions, constraints, traps, candidates, handoffs, plans, sequences) using BM25 scoring.',
|
|
115
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'auto' },
|
|
116
|
+
inputSchema: {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties: {
|
|
119
|
+
query: { type: 'string', description: 'Search query string.' },
|
|
120
|
+
type: { type: 'string', description: 'Filter by section: decisions, constraints, traps, handoffs, candidates, plans, sequences.' },
|
|
121
|
+
section: { type: 'string', description: 'Filter by section (state, candidates, runtime).' },
|
|
122
|
+
since: { type: 'string', description: 'Filter items created after this ISO date.' },
|
|
123
|
+
project: { type: 'string', description: 'Optional project name/path to search. Defaults to the active project.' },
|
|
124
|
+
includeLegacy: { type: 'boolean', description: 'Include records with provenance.kind="legacy" (default false). Response reports excluded_legacy when false.' },
|
|
125
|
+
limit: { type: 'number', description: 'Maximum number of results to return (default 10).' },
|
|
126
|
+
offset: { type: 'number', description: 'Number of results to skip (for pagination).' },
|
|
127
|
+
budget_tokens: { type: 'number', description: 'Optional token budget for the result page (~4 chars/token). The page is size-bounded; has_more/next_offset advertise the rest.' },
|
|
128
|
+
},
|
|
129
|
+
required: ['query'],
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'bclaw_estimation_report',
|
|
134
|
+
description: 'Show estimation accuracy report for completed plans. Returns ratio of estimated vs actual effort per agent.',
|
|
135
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: 'object',
|
|
138
|
+
properties: {
|
|
139
|
+
agent: { type: 'string', description: 'Filter by agent/author name.' },
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'bclaw_list_sequences',
|
|
145
|
+
description: 'List coordination sequences with optional filters on status and id.',
|
|
146
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
147
|
+
inputSchema: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {
|
|
150
|
+
status: { type: 'string', description: 'Filter by status: draft, active, archived.' },
|
|
151
|
+
id: { type: 'string', description: 'Get a single sequence by ID or short label.' },
|
|
152
|
+
limit: { type: 'number', description: 'Maximum number of sequences to return (default: 20).' },
|
|
153
|
+
offset: { type: 'number', description: 'Number of sequences to skip (for pagination).' },
|
|
154
|
+
compact: { type: 'boolean', description: 'Return only key fields (id, name, status) to reduce output size.' },
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'bclaw_assignment_events',
|
|
160
|
+
description: 'List correlated runtime events for assignments and runs with filters on assignment, run, claim, session, agent, or event type.',
|
|
161
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {
|
|
165
|
+
assignmentId: { type: 'string', description: 'Filter by linked assignment ID.' },
|
|
166
|
+
runId: { type: 'string', description: 'Filter by linked run ID.' },
|
|
167
|
+
claimId: { type: 'string', description: 'Filter by linked claim ID.' },
|
|
168
|
+
sessionId: { type: 'string', description: 'Filter by runtime session ID.' },
|
|
169
|
+
agent: { type: 'string', description: 'Filter by agent name.' },
|
|
170
|
+
eventType: { type: 'string', description: 'Filter by runtime event type.' },
|
|
171
|
+
id: { type: 'string', description: 'Get a single runtime event by ID.' },
|
|
172
|
+
limit: { type: 'number', description: 'Maximum number of events to return (default: 20).' },
|
|
173
|
+
offset: { type: 'number', description: 'Number of events to skip (for pagination).' },
|
|
174
|
+
compact: { type: 'boolean', description: 'Return only key fields to reduce output size.' },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'bclaw_list_agents',
|
|
180
|
+
description: 'List registered agent identities and optionally include bounded reputation summaries.',
|
|
181
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
182
|
+
inputSchema: {
|
|
183
|
+
type: 'object',
|
|
184
|
+
properties: {
|
|
185
|
+
includeReputation: { type: 'boolean', description: 'Include bounded reputation summaries for each agent.' },
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: 'bclaw_list_instructions',
|
|
191
|
+
description: 'List raw or resolved shared instructions with the same filters exposed by the CLI.',
|
|
192
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
193
|
+
inputSchema: {
|
|
194
|
+
type: 'object',
|
|
195
|
+
properties: {
|
|
196
|
+
layer: { type: 'string', description: 'Filter by layer: global, project, agent.' },
|
|
197
|
+
project: { type: 'string', description: 'Project namespace filter.' },
|
|
198
|
+
agent: { type: 'string', description: 'Agent name filter.' },
|
|
199
|
+
active: { type: 'boolean', description: 'Only include active instructions.' },
|
|
200
|
+
resolved: { type: 'boolean', description: 'Resolve effective instructions for the given scope.' },
|
|
201
|
+
path: { type: 'string', description: 'Infer project namespace from a target path when strategy=folder.' },
|
|
202
|
+
limit: { type: 'number', description: 'Maximum number of instructions to return (default: 20).' },
|
|
203
|
+
offset: { type: 'number', description: 'Number of instructions to skip (for pagination).' },
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: 'bclaw_get_capabilities',
|
|
209
|
+
description: 'List all registered project capabilities with full metadata.',
|
|
210
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
211
|
+
inputSchema: {
|
|
212
|
+
type: 'object',
|
|
213
|
+
properties: {
|
|
214
|
+
category: { type: 'string', description: 'Filter by capability category.' },
|
|
215
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags (any).' },
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: 'bclaw_list_tools',
|
|
221
|
+
description: 'List all registered project tools with metadata.',
|
|
222
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
223
|
+
inputSchema: {
|
|
224
|
+
type: 'object',
|
|
225
|
+
properties: {
|
|
226
|
+
type: { type: 'string', description: 'Filter by tool type (workflow, validator, generator, utility, explorer).' },
|
|
227
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags (any).' },
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'bclaw_search_tools',
|
|
233
|
+
description: 'Search tools by query and tags.',
|
|
234
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
235
|
+
inputSchema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
query: { type: 'string', description: 'Search query (matches tool name, description, tags).' },
|
|
239
|
+
type: { type: 'string', description: 'Filter by tool type.' },
|
|
240
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags (all must match).' },
|
|
241
|
+
},
|
|
242
|
+
required: ['query'],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'bclaw_doctor',
|
|
247
|
+
description: 'Run health checks on the brainclaw memory store. Returns structured check results with ok/warn/error status and metrics.',
|
|
248
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
249
|
+
inputSchema: {
|
|
250
|
+
type: 'object',
|
|
251
|
+
properties: {
|
|
252
|
+
migrationCheck: { type: 'boolean', description: 'Include detailed schema migration status.' },
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
name: 'bclaw_history',
|
|
258
|
+
description: 'Show full mutation history of a memory item from the audit log.',
|
|
259
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
260
|
+
inputSchema: {
|
|
261
|
+
type: 'object',
|
|
262
|
+
properties: {
|
|
263
|
+
id: { type: 'string', description: 'Item ID to retrieve history for.' },
|
|
264
|
+
},
|
|
265
|
+
required: ['id'],
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: 'bclaw_audit',
|
|
270
|
+
description: 'View the audit log or generate a governance posture report. Use governance=true for an aggregated view of claims, constraints, traps, instructions and recommendations.',
|
|
271
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
272
|
+
inputSchema: {
|
|
273
|
+
type: 'object',
|
|
274
|
+
properties: {
|
|
275
|
+
since: { type: 'string', description: 'Show entries since this ISO date.' },
|
|
276
|
+
actor: { type: 'string', description: 'Filter by actor name or agent ID.' },
|
|
277
|
+
action: { type: 'string', description: 'Filter by action type (create, accept, reject, etc.).' },
|
|
278
|
+
limit: { type: 'number', description: 'Show last N entries (default 20).' },
|
|
279
|
+
governance: { type: 'boolean', description: 'Generate a governance posture report instead of chronological log.' },
|
|
280
|
+
scope: { type: 'string', description: 'Filter governance report by scope (used with governance=true).' },
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'bclaw_get_discovery',
|
|
286
|
+
description: 'Scan workspace for MCP configs, instruction files, skills, hooks, and agent integrations. Returns a structured discovery profile. Saves result to .brainclaw/discovery/ by default.',
|
|
287
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
properties: {
|
|
291
|
+
refresh: { type: 'boolean', description: 'Force a fresh scan even if a cached profile exists (default: true).' },
|
|
292
|
+
noSave: { type: 'boolean', description: 'Do not persist the discovery profile.' },
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
name: 'bclaw_conflict_check',
|
|
298
|
+
description: 'Check for claim conflicts between the current agent and other agents. Returns overlapping scopes.',
|
|
299
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
300
|
+
inputSchema: {
|
|
301
|
+
type: 'object',
|
|
302
|
+
properties: {
|
|
303
|
+
agent: { type: 'string', description: 'Agent name to check conflicts for (default: current agent).' },
|
|
304
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
name: 'bclaw_who',
|
|
310
|
+
description: 'List all active agent sessions on this workspace. Shows user, agent, active project, claims, and last activity for each session.',
|
|
311
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'auto' },
|
|
312
|
+
inputSchema: {
|
|
313
|
+
type: 'object',
|
|
314
|
+
properties: {
|
|
315
|
+
all: { type: 'boolean', description: 'Include stale sessions (default: false).' },
|
|
316
|
+
gc: { type: 'boolean', description: 'Remove stale sessions and return count.' },
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'bclaw_switch',
|
|
322
|
+
description: 'Switch active project in a multi-project workspace. Session-scoped by default: only this agent sees the switch, other agents are unaffected. Use list=true to see available projects.',
|
|
323
|
+
annotations: { tier: 'standard', category: 'session', headlessApproval: 'prompt' },
|
|
324
|
+
inputSchema: {
|
|
325
|
+
type: 'object',
|
|
326
|
+
properties: {
|
|
327
|
+
project: { type: 'string', description: 'Project reference: name, path, or project_id.' },
|
|
328
|
+
list: { type: 'boolean', description: 'List available projects instead of switching.' },
|
|
329
|
+
clear: { type: 'boolean', description: 'Clear active project (return to workspace root).' },
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
name: 'bclaw_check_policy',
|
|
335
|
+
description: 'Pre-execution policy check. Verifies claims, constraints, traps and governance instructions for a given scope. Returns blocks (hard stops) and warnings (context to consider). Call before editing to ensure compliance.',
|
|
336
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
337
|
+
inputSchema: {
|
|
338
|
+
type: 'object',
|
|
339
|
+
properties: {
|
|
340
|
+
scope: { type: 'string', description: 'File or directory scope to check (e.g. "src/core/foo.ts" or "src/commands").' },
|
|
341
|
+
agent: { type: 'string', description: 'Agent name to check claims for.' },
|
|
342
|
+
agentId: { type: 'string', description: 'Agent id to check claims for.' },
|
|
343
|
+
action: { type: 'string', description: 'Intended action: edit, create, delete (informational, does not change check logic in v1).' },
|
|
344
|
+
},
|
|
345
|
+
required: ['scope'],
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
name: 'bclaw_check_security',
|
|
350
|
+
description: 'Check supply chain security scores for packages via Socket.dev. Returns pass/warn/block verdict per package. Requires security.preinstall.enabled in config. Uses the free public Socket MCP endpoint (no auth needed).',
|
|
351
|
+
annotations: { tier: 'advanced', category: 'governance', headlessApproval: 'auto' },
|
|
352
|
+
inputSchema: {
|
|
353
|
+
type: 'object',
|
|
354
|
+
properties: {
|
|
355
|
+
packages: { type: 'string', description: 'Comma-separated package names (e.g. "axios,express" or "axios@1.14.1").' },
|
|
356
|
+
ecosystem: { type: 'string', description: 'Package ecosystem: npm or pypi. Defaults to npm.' },
|
|
357
|
+
},
|
|
358
|
+
required: ['packages'],
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: 'bclaw_read_inbox',
|
|
363
|
+
description: 'Read messages from an agent inbox. Returns pending messages by default. Use markAsRead to auto-mark pending messages as read. Supports filtering by status, type, and thread_id.',
|
|
364
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
365
|
+
inputSchema: {
|
|
366
|
+
type: 'object',
|
|
367
|
+
properties: {
|
|
368
|
+
agent: { type: 'string', description: 'Agent name whose inbox to read. Defaults to calling agent.' },
|
|
369
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
370
|
+
status: { type: 'string', description: 'Filter by status: pending, read, acknowledged, archived.' },
|
|
371
|
+
type: { type: 'string', description: 'Filter by message type: assign, review, rfc, info, reply.' },
|
|
372
|
+
thread_id: { type: 'string', description: 'Filter by thread ID to see a conversation.' },
|
|
373
|
+
markAsRead: { type: 'boolean', description: 'Mark pending messages as read. Default: false.' },
|
|
374
|
+
limit: { type: 'number', description: 'Maximum messages to return (default: 20).' },
|
|
375
|
+
offset: { type: 'number', description: 'Skip N messages for pagination.' },
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
name: 'bclaw_get_thread',
|
|
381
|
+
description: 'Get all messages in a thread across all agent inboxes. Useful for following RFC discussions or review rounds.',
|
|
382
|
+
annotations: { tier: 'advanced', category: 'coordination', headlessApproval: 'auto' },
|
|
383
|
+
inputSchema: {
|
|
384
|
+
type: 'object',
|
|
385
|
+
properties: {
|
|
386
|
+
thread_id: { type: 'string', description: 'Thread ID to retrieve.' },
|
|
387
|
+
},
|
|
388
|
+
required: ['thread_id'],
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
name: 'bclaw_dispatch_status',
|
|
393
|
+
description: 'Consolidated dispatch status — given a `target_id` (asgn_/clm_/lop_/run_), resolves all linked entities (assignment, claim, loop, agent_run), reads the on-disk artefacts (brief-ack sentinel + per-assignment stdout/stderr log tails), checks OS pid liveness, and returns a single health verdict + a recommended next action. Replaces the five separate `bclaw_find` / `bclaw_get` calls a caller would otherwise make to verify a dispatch is actually doing useful work. Particularly useful right after `bclaw_coordinate` returns `execution_status="delivered_and_started"` — that response\'s `verify_with` hint points at this tool by name. See docs/concepts/dispatch-lifecycle.md for the full entity model and FSM details.',
|
|
394
|
+
annotations: { tier: 'facade', category: 'coordination', headlessApproval: 'auto' },
|
|
395
|
+
inputSchema: {
|
|
396
|
+
type: 'object',
|
|
397
|
+
properties: {
|
|
398
|
+
target_id: { type: 'string', description: 'Any one of: an assignment id (`asgn_…`), a claim id (`clm_…`), a loop id (`lop_…`), or an agent_run id (`run_…`). The tool resolves to the assignment scope internally and fetches the rest.' },
|
|
399
|
+
tail_log_lines: { type: 'number', description: 'How many trailing lines of each captured log file (stdout / stderr) to include in the response. Default 20. Pass 0 to omit tails and only return size_bytes.' },
|
|
400
|
+
stall_threshold_ms: { type: 'number', description: 'Age in ms past which a `running` agent_run with a live pid but no recent activity is considered `stalled`. Default 300000 (5 min).' },
|
|
401
|
+
},
|
|
402
|
+
required: ['target_id'],
|
|
403
|
+
},
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'bclaw_code_status',
|
|
407
|
+
description: 'Code Map status for this project: store presence, freshness badge (fresh / stale_changed_files / stale_extractor / stale_grammar / stale_git_head / partial / missing_index), and index stats (files, nodes, edges). Read-only; never refreshes. Pair with bclaw_code_refresh when freshness is missing_index or stale. In a multi-project workspace, cascade=true adds a per-child recap (which nested projects have a built index vs missing_index).',
|
|
408
|
+
annotations: { tier: 'standard', category: 'discovery', headlessApproval: 'auto' },
|
|
409
|
+
inputSchema: {
|
|
410
|
+
type: 'object',
|
|
411
|
+
properties: {
|
|
412
|
+
cascade: { type: 'boolean', description: 'Multi-project workspace recap: also report per-child store presence + freshness for every nested project. No-op outside a multi-project workspace.' },
|
|
413
|
+
},
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
name: 'bclaw_code_find',
|
|
418
|
+
description: 'Search the Code Map symbol index for a query (function/class/component/hook/type names). Returns ranked matches with path + score, plus a freshness_badge from the lazy read-path check. Read-only; never refreshes — a missing_index badge means run bclaw_code_refresh first.',
|
|
419
|
+
annotations: { tier: 'standard', category: 'discovery', headlessApproval: 'auto' },
|
|
420
|
+
inputSchema: {
|
|
421
|
+
type: 'object',
|
|
422
|
+
properties: {
|
|
423
|
+
query: { type: 'string', description: 'Symbol or token to search for (e.g. "App", "useAuth", "dispatch").' },
|
|
424
|
+
limit: { type: 'number', description: 'Max matches to return.' },
|
|
425
|
+
},
|
|
426
|
+
required: ['query'],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
name: 'bclaw_code_brief',
|
|
431
|
+
description: 'Before editing, ask Code Map what to read: returns a ranked suggested_files_to_read list (cap 12) for a symbol or path, related brainclaw memory (cap 5), and a freshness_badge. Read-only; never refreshes.',
|
|
432
|
+
annotations: { tier: 'standard', category: 'discovery', headlessApproval: 'auto' },
|
|
433
|
+
inputSchema: {
|
|
434
|
+
type: 'object',
|
|
435
|
+
properties: {
|
|
436
|
+
target: { type: 'string', description: 'Symbol name or file path to build a reading brief for.' },
|
|
437
|
+
limit: { type: 'number', description: 'Max suggested files (hard-capped at 12 by the spec).' },
|
|
438
|
+
},
|
|
439
|
+
required: ['target'],
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
];
|
|
443
|
+
const MCP_WRITE_TOOLS = [
|
|
444
|
+
{
|
|
445
|
+
name: 'bclaw_code_refresh',
|
|
446
|
+
description: 'Rebuild the Code Map index for this project (Tree-sitter parse + shards + indexes, behind the per-project lock). scope="changed" (default) reparses changed files; scope="all" does a full refresh + compaction. A live competing lock fails fast with a clear status — refresh never blocks. Returns the resulting freshness_badge. In a multi-project workspace, cascade=true refreshes EVERY nested project into its own store + the root store scoped to files no child owns (zero double-indexing) — so one call at the root indexes the whole monorepo per-project.',
|
|
447
|
+
annotations: { tier: 'standard', category: 'discovery', headlessApproval: 'prompt' },
|
|
448
|
+
inputSchema: {
|
|
449
|
+
type: 'object',
|
|
450
|
+
properties: {
|
|
451
|
+
scope: { type: 'string', enum: ['changed', 'all'], description: 'changed (default) reparses changed files only; all does a full refresh with orphan compaction.' },
|
|
452
|
+
cascade: { type: 'boolean', description: 'Multi-project cascade: refresh every nested brainclaw project + a child-scoped root store. No-op outside a multi-project workspace.' },
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
name: 'bclaw_dispatch',
|
|
458
|
+
description: 'Unified dispatch entry for sequence-lane parallelization (parallelize plans across lanes). To open a NEW review of a commit/branch, use `bclaw_coordinate(intent="review", open_loop=true, targetAgents=[…])` instead — bclaw_dispatch is for sequence-driven execution, NOT for opening new reviews. `intent` discriminator: analysis (sequence lane status, read-only), execute (default — analyze + generate briefs + send to agents), review (routes an EXISTING already-reflected handoff to a reviewer — only for handoffs produced by `session-end --reflect-handoff` or similar). Consolidates the legacy bclaw_dispatch_analysis / bclaw_dispatch / bclaw_dispatch_review. Returns FacadeResponse; for verification semantics see the same response-validation guidance documented on `bclaw_coordinate`.',
|
|
459
|
+
annotations: { tier: 'facade', category: 'coordination', headlessApproval: 'prompt' },
|
|
460
|
+
inputSchema: {
|
|
461
|
+
type: 'object',
|
|
462
|
+
properties: {
|
|
463
|
+
intent: { type: 'string', enum: ['analysis', 'execute', 'review'], description: 'Dispatch intent. Default: execute.' },
|
|
464
|
+
// intent=execute args
|
|
465
|
+
agents: { type: 'array', items: { type: 'string' }, description: 'Only dispatch to these agents. Default: all available.' },
|
|
466
|
+
lanes: { type: 'array', items: { type: 'string' }, description: 'Only dispatch items in these lanes. Also used by intent=analysis.' },
|
|
467
|
+
maxAssignments: { type: 'number', description: 'Max assignments to make (default: all ready). intent=execute only.' },
|
|
468
|
+
model: { type: 'string', description: 'Model to run on spawned workers, decoupled from agent identity (e.g. "sonnet", "gpt-5-codex"). Injected as `<model_flag> <model>` for agents that declare one (claude-code/codex/copilot); no-op for template-pinned identities. Mirrors the CLI `brainclaw dispatch run --model`. intent=execute only.' },
|
|
469
|
+
dryRun: { type: 'boolean', description: 'Preview without sending. Accepted by all intents.' },
|
|
470
|
+
autoExecute: { type: 'boolean', description: 'Attempt to spawn agents after delivery (default: true). intent=execute only.' },
|
|
471
|
+
// intent=review args (forwarded to bclaw_dispatch_review)
|
|
472
|
+
handoffId: { type: 'string', description: 'intent=review: specific handoff ID. Default: auto-detect reviewable handoffs.' },
|
|
473
|
+
reviewer: { type: 'string', description: 'intent=review: specific reviewer agent. Default: any available non-author.' },
|
|
474
|
+
openLoop: { type: 'boolean', description: 'intent=review: open a review_loop alongside the inbox message (default true).' },
|
|
475
|
+
reviewMode: { type: 'string', enum: ['asymmetric', 'symmetric'], description: 'intent=review: loop mode when openLoop=true.' },
|
|
476
|
+
// Common
|
|
477
|
+
agent: { type: 'string', description: 'Dispatcher agent name.' },
|
|
478
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: 'bclaw_send_message',
|
|
484
|
+
description: 'Send a message to another agent\'s inbox. Used for work assignment (type: assign), review requests (type: review), RFC discussions (type: rfc), notifications (type: info), and threaded replies (type: reply). Requires contributor trust.',
|
|
485
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
486
|
+
inputSchema: {
|
|
487
|
+
type: 'object',
|
|
488
|
+
properties: {
|
|
489
|
+
to: { type: 'string', description: 'Target agent name.' },
|
|
490
|
+
type: { type: 'string', description: 'Message type: assign, review, rfc, info, reply.' },
|
|
491
|
+
text: { type: 'string', description: 'Message body.' },
|
|
492
|
+
ref: { type: 'string', description: 'Reference to a plan, sequence, handoff, or other entity ID.' },
|
|
493
|
+
payload: { type: 'object', description: 'Structured data (brief, criteria, context).' },
|
|
494
|
+
scope: { type: 'string', description: 'File scope relevant to this message.' },
|
|
495
|
+
requires_ack: { type: 'boolean', description: 'Require recipient to acknowledge. Default: false.' },
|
|
496
|
+
thread_id: { type: 'string', description: 'Thread ID for multi-turn conversations. Omit to start a new thread.' },
|
|
497
|
+
agent: { type: 'string', description: 'Sender agent name.' },
|
|
498
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
499
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Optional tags.' },
|
|
500
|
+
},
|
|
501
|
+
required: ['to', 'type', 'text'],
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: 'bclaw_ack_message',
|
|
506
|
+
description: 'Acknowledge a message in your inbox. Use after processing an assignment or review request.',
|
|
507
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
508
|
+
inputSchema: {
|
|
509
|
+
type: 'object',
|
|
510
|
+
properties: {
|
|
511
|
+
id: { type: 'string', description: 'Message ID or short label to acknowledge.' },
|
|
512
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
513
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
514
|
+
},
|
|
515
|
+
required: ['id'],
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
name: 'bclaw_setup',
|
|
520
|
+
description: 'Interactive onboarding wizard. Two modes: (1) Quick mode (default): probes the current repo and asks project type + topology, then inits. (2) Batch mode: scan root directories and init multiple repos. Call without step to start — brainclaw auto-detects the best mode.',
|
|
521
|
+
annotations: { tier: 'facade', category: 'session', headlessApproval: 'prompt' },
|
|
522
|
+
inputSchema: {
|
|
523
|
+
type: 'object',
|
|
524
|
+
properties: {
|
|
525
|
+
step: { type: 'string', description: 'Resume step: "quick_init" (quick mode), or "project_roots"/"repo_selection"/"agent_selection" (batch mode). Omit to start.' },
|
|
526
|
+
choice: { type: 'string', description: 'User choice for the current step.' },
|
|
527
|
+
project_type: { type: 'string', description: 'Quick mode: "standalone", "workspace", or "linked".' },
|
|
528
|
+
topology: { type: 'string', description: 'Quick mode: "embedded" (shared via git) or "sidecar" (local only).' },
|
|
529
|
+
roots: { type: 'string', description: 'Batch mode: comma-separated root paths.' },
|
|
530
|
+
repo_selection: { type: 'string', description: 'Batch mode: repo selection from previous step.' },
|
|
531
|
+
mode: { type: 'string', description: 'Force "quick" or "batch" mode. Default: auto-detect.' },
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
name: 'bclaw_init_project',
|
|
537
|
+
description: "Initialize brainclaw at an arbitrary path AND register it as a cross_project_link in the caller's store. Lets an agent operating in workspace A bootstrap a brainclaw project in folder B in one MCP call.",
|
|
538
|
+
annotations: { tier: 'standard', category: 'session', headlessApproval: 'prompt' },
|
|
539
|
+
inputSchema: {
|
|
540
|
+
type: 'object',
|
|
541
|
+
properties: {
|
|
542
|
+
path: { type: 'string', description: 'Absolute or relative path of the target folder. Resolved via path.resolve(callerCwd, path).' },
|
|
543
|
+
force: { type: 'boolean', description: 'Pass --force to init (rebuild managed config). Default false.' },
|
|
544
|
+
project_mode: { type: 'string', description: 'Optional project mode (single-project, multi-project, auto).' },
|
|
545
|
+
link_as: { type: 'string', description: 'Optional name to register the cross_project_link under. Defaults to path basename.' },
|
|
546
|
+
},
|
|
547
|
+
required: ['path'],
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
name: 'bclaw_write_note',
|
|
552
|
+
description: 'Add a runtime note. Requires contributor trust level or above. Use crossProject to push a runtime-note signal to a linked project (requires role: publisher in cross_project_links config).',
|
|
553
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'auto' },
|
|
554
|
+
inputSchema: {
|
|
555
|
+
type: 'object',
|
|
556
|
+
properties: {
|
|
557
|
+
text: { type: 'string', description: 'Note content.' },
|
|
558
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
559
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
560
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Optional tags.' },
|
|
561
|
+
visibility: { type: 'string', description: 'Visibility: shared, machine, private.' },
|
|
562
|
+
ttl: { type: 'string', description: 'Optional TTL: 30m, 2h, 7d.' },
|
|
563
|
+
autoReflect: { type: 'boolean', description: 'Attempt to reflect the runtime note into durable memory immediately.' },
|
|
564
|
+
crossProject: { type: 'string', description: 'Push note to a linked project (name or path). Requires role: publisher in cross_project_links config.' },
|
|
565
|
+
cross_project: { type: 'string', description: 'Snake_case alias of crossProject.' },
|
|
566
|
+
},
|
|
567
|
+
required: ['text'],
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
name: 'bclaw_quick_capture',
|
|
572
|
+
description: 'Capture free-form text as a decision, trap, constraint, or runtime note. Declare `type` yourself (you know what you are capturing — caller assertion wins); keyword heuristics are only a fallback when type is absent. Contradictions with existing memory are attached as advisory metadata on the candidate, never block promotion.',
|
|
573
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'auto' },
|
|
574
|
+
inputSchema: {
|
|
575
|
+
type: 'object',
|
|
576
|
+
properties: {
|
|
577
|
+
text: { type: 'string', description: 'Free-form capture text.' },
|
|
578
|
+
type: { type: 'string', enum: ['decision', 'trap', 'constraint', 'note'], description: 'Caller-asserted classification. Strongly recommended — the calling agent knows the nature of the capture better than keyword heuristics (cnd_abe61d68: 18 false contradiction positives on a review summary).' },
|
|
579
|
+
context: { type: 'string', description: 'Optional file/path/scope context to associate with the capture.' },
|
|
580
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
581
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
582
|
+
},
|
|
583
|
+
required: ['text'],
|
|
584
|
+
},
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
name: 'bclaw_claim',
|
|
588
|
+
description: 'Claim a work scope (advisory lock). By default creates an isolated git worktree for the claim (multi-agent safety). Pass advisory:true (or worktree:false) for an advisory-only lock with NO worktree — use this when the work already lives uncommitted in the main tree and a fresh worktree would be counterproductive (trp#431). Requires contributor trust level or above.',
|
|
589
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
590
|
+
inputSchema: {
|
|
591
|
+
type: 'object',
|
|
592
|
+
properties: {
|
|
593
|
+
scope: { type: 'string', description: 'Scope being claimed.' },
|
|
594
|
+
description: { type: 'string', description: 'Description of the work.' },
|
|
595
|
+
agent: { type: 'string', description: 'Agent or person name.' },
|
|
596
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
597
|
+
planId: { type: 'string', description: 'Optional linked plan item ID.' },
|
|
598
|
+
project: { type: 'string', description: 'Project name or path. Use this when working on a project different from the MCP server workspace (e.g. CLI agents in a different directory).' },
|
|
599
|
+
store: { type: 'string', description: 'Target store level: local (default), repo, workspace.' },
|
|
600
|
+
worktreeBranch: { type: 'string', description: 'Branch name for the worktree. Defaults to feat/<scope-slug>.' },
|
|
601
|
+
worktree: { type: 'boolean', description: 'Whether to create an isolated git worktree (default true). Pass false for an advisory-only lock with no worktree (trp#431) — for in-place work in the main tree.' },
|
|
602
|
+
advisory: { type: 'boolean', description: 'Alias for worktree:false — advisory-only lock with no worktree (trp#431).' },
|
|
603
|
+
handoffMode: { type: 'string', enum: ['self-commit', 'integrator'], description: 'Handoff mode: "self-commit" (worker commits+merges) or "integrator" (another agent reviews+merges). Default: self-commit.' },
|
|
604
|
+
},
|
|
605
|
+
required: ['scope', 'description'],
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
name: 'bclaw_release_claim',
|
|
610
|
+
description: 'Release a work claim. Callers own their own claims; a trusted+ coordinator releasing another agent\'s claim MUST pass coordinator_override:true (audited).',
|
|
611
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
612
|
+
inputSchema: {
|
|
613
|
+
type: 'object',
|
|
614
|
+
properties: {
|
|
615
|
+
id: { type: 'string', description: 'Claim ID to release.' },
|
|
616
|
+
planStatus: { type: 'string', description: 'Optional: update linked plan status.' },
|
|
617
|
+
coordinator_override: {
|
|
618
|
+
type: 'boolean',
|
|
619
|
+
description: 'Opt-in override for a trusted+ caller releasing a claim they do NOT own (cross-agent teardown, ghost-claim cleanup). Rejected for contributor-level callers; audited when used. trp#928.',
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
required: ['id'],
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
name: 'bclaw_session_start',
|
|
627
|
+
description: 'Start a session and capture initial context. Pass includeContext and/or includeBoard to get full context + agent board in a single call, eliminating the need for separate bclaw_get_context and bclaw_get_agent_board calls.',
|
|
628
|
+
annotations: { tier: 'standard', category: 'session', headlessApproval: 'auto' },
|
|
629
|
+
inputSchema: {
|
|
630
|
+
type: 'object',
|
|
631
|
+
properties: {
|
|
632
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
633
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
634
|
+
context: { type: 'string', description: 'Context target path.' },
|
|
635
|
+
maintenanceMode: { type: 'string', enum: ['fast', 'full'], description: 'Maintenance mode. Default is full for explicit session-start calls; use fast to skip non-critical maintenance work.' },
|
|
636
|
+
includeContext: { type: 'boolean', description: 'Include project memory context in the response (equivalent to bclaw_get_context).' },
|
|
637
|
+
includeBoard: { type: 'boolean', description: 'Include agent board (plans, claims, handoffs) in the response (equivalent to bclaw_get_agent_board).' },
|
|
638
|
+
contextProfile: { type: 'string', description: 'Context profile when includeContext is true: dev (default), dense, compact, copilot, quick, briefing, openclaw, ops, research. If unset, uses the agent default profile.' },
|
|
639
|
+
contextFormat: { type: 'string', description: 'Context format when includeContext is true: markdown, json, or template.' },
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
name: 'bclaw_session_end',
|
|
645
|
+
description: 'End a session and optionally auto-reflect observations as candidates.',
|
|
646
|
+
annotations: { tier: 'standard', category: 'session', headlessApproval: 'auto' },
|
|
647
|
+
inputSchema: {
|
|
648
|
+
type: 'object',
|
|
649
|
+
properties: {
|
|
650
|
+
session: { type: 'string', description: 'Session ID.' },
|
|
651
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
652
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
653
|
+
summary: { type: 'string', description: 'Session summary text.' },
|
|
654
|
+
narrative: { type: 'string', description: 'Free-text narrative of what happened in the session and why. Goes beyond the auto-generated commit list: "Tried X, failed because Y, pivoted to Z. Watch out for A."' },
|
|
655
|
+
autoReflect: { type: 'boolean', description: 'Auto-reflect session notes as candidates.' },
|
|
656
|
+
autoRelease: { type: 'boolean', description: 'Auto-release any active claims at session end.' },
|
|
657
|
+
reflectHandoff: { type: 'boolean', description: 'Materialize an open handoff from git commits since session start.' },
|
|
658
|
+
dispatchReview: { type: 'boolean', description: 'When used with reflectHandoff, auto-dispatch a code review if the reflected handoff is reviewable.' },
|
|
659
|
+
reviewer: { type: 'string', description: 'Explicit reviewer for the reflected handoff review dispatch.' },
|
|
660
|
+
reflect: { type: 'boolean', description: 'Emit the dogfooding reflection prompt (project + your surfaces/skills/tools). Default true — pass false to suppress on a trivial session. Capture actionable findings via bclaw_quick_capture.' },
|
|
661
|
+
},
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
name: 'bclaw_create_sequence',
|
|
666
|
+
description: 'Create a coordination sequence shared by agents.',
|
|
667
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'prompt' },
|
|
668
|
+
inputSchema: {
|
|
669
|
+
type: 'object',
|
|
670
|
+
properties: {
|
|
671
|
+
name: { type: 'string', description: 'Sequence name.' },
|
|
672
|
+
description: { type: 'string', description: 'Optional sequence description.' },
|
|
673
|
+
status: { type: 'string', description: 'Status: draft, active, archived.' },
|
|
674
|
+
owner: { type: 'string', description: 'Optional sequence owner.' },
|
|
675
|
+
items: { type: 'array', description: 'Sequence items in rank order.', items: SEQUENCE_ITEM_INPUT_SCHEMA },
|
|
676
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Optional tags.' },
|
|
677
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
678
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
679
|
+
},
|
|
680
|
+
required: ['name'],
|
|
681
|
+
},
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
name: 'bclaw_update_sequence',
|
|
685
|
+
description: 'Update a coordination sequence status, metadata, or items.',
|
|
686
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'prompt' },
|
|
687
|
+
inputSchema: {
|
|
688
|
+
type: 'object',
|
|
689
|
+
properties: {
|
|
690
|
+
id: { type: 'string', description: 'Sequence ID or short label.' },
|
|
691
|
+
name: { type: 'string', description: 'Optional new sequence name.' },
|
|
692
|
+
description: { type: 'string', description: 'Optional new description.' },
|
|
693
|
+
status: { type: 'string', description: 'Status: draft, active, archived.' },
|
|
694
|
+
owner: { type: 'string', description: 'Optional sequence owner.' },
|
|
695
|
+
items: { type: 'array', description: 'Optional replacement items array.', items: SEQUENCE_ITEM_INPUT_SCHEMA },
|
|
696
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Optional replacement tags.' },
|
|
697
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
698
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
699
|
+
},
|
|
700
|
+
required: ['id'],
|
|
701
|
+
},
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
name: 'bclaw_add_step',
|
|
705
|
+
description: 'Add a sub-step to a plan item. Canonical shape is `{ planId, data: { text, title?, assignee? } }`; legacy top-level `{ text, assignee }` still works for backward compatibility. If both are present, data.* wins and a warning is emitted. Requires contributor trust level or above. Pass `project` to target a step in a plan that lives in a linked project (same pattern as the canonical-grammar tools).',
|
|
706
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
707
|
+
inputSchema: {
|
|
708
|
+
type: 'object',
|
|
709
|
+
properties: {
|
|
710
|
+
planId: { type: 'string', description: 'Plan item ID.' },
|
|
711
|
+
data: {
|
|
712
|
+
type: 'object',
|
|
713
|
+
description: 'Canonical step payload: { text, title?, assignee? }. title is accepted as an alias for text.',
|
|
714
|
+
properties: {
|
|
715
|
+
text: { type: 'string', description: 'Step description.' },
|
|
716
|
+
title: { type: 'string', description: 'Alias for text.' },
|
|
717
|
+
assignee: { type: 'string', description: 'Optional assignee.' },
|
|
718
|
+
estimated_effort: { type: 'number', description: 'Step-level estimate in minutes (pln#495). A duration string like "2h"/"30m" is also accepted and coerced.' },
|
|
719
|
+
actual_effort: { type: 'string', description: 'Step-level actual effort, free-form ("45m", "2h"), parsed when the estimation report runs.' },
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
text: { type: 'string', description: 'Legacy top-level step description; prefer data.text.' },
|
|
723
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
724
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
725
|
+
assignee: { type: 'string', description: 'Legacy top-level optional assignee; prefer data.assignee.' },
|
|
726
|
+
project: { type: 'string', description: 'Optional: name (or path/basename) of a linked project to add the step in. Defaults to the current project. Same resolution as canonical-grammar tools — accepts cross_project_links and workspace store-chain children.' },
|
|
727
|
+
},
|
|
728
|
+
required: ['planId'],
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
{
|
|
732
|
+
name: 'bclaw_complete_step',
|
|
733
|
+
description: 'Mark a plan sub-step as done. Requires contributor trust level or above. Pass `project` to operate on a plan in a linked project.',
|
|
734
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
735
|
+
inputSchema: {
|
|
736
|
+
type: 'object',
|
|
737
|
+
properties: {
|
|
738
|
+
planId: { type: 'string', description: 'Plan item ID.' },
|
|
739
|
+
stepId: { type: 'string', description: 'Step ID to complete.' },
|
|
740
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
741
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
742
|
+
project: { type: 'string', description: 'Optional: name of a linked project to complete the step in. Defaults to the current project.' },
|
|
743
|
+
},
|
|
744
|
+
required: ['planId', 'stepId'],
|
|
745
|
+
},
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
name: 'bclaw_update_step',
|
|
749
|
+
description: 'Update a plan sub-step (status, text, assignee). Supports all step statuses: todo, in_progress, testing, done, blocked. Requires contributor trust level or above. Pass `project` to operate on a plan in a linked project.',
|
|
750
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
751
|
+
inputSchema: {
|
|
752
|
+
type: 'object',
|
|
753
|
+
properties: {
|
|
754
|
+
planId: { type: 'string', description: 'Plan item ID.' },
|
|
755
|
+
stepId: { type: 'string', description: 'Step ID to update.' },
|
|
756
|
+
status: { type: 'string', description: 'New status: todo, in_progress, testing, done, blocked.' },
|
|
757
|
+
text: { type: 'string', description: 'New step text.' },
|
|
758
|
+
assignee: { type: 'string', description: 'New assignee (empty string to unassign).' },
|
|
759
|
+
estimated_effort: { type: 'number', description: 'Step-level estimate in minutes (pln#495); a duration string is also coerced.' },
|
|
760
|
+
actual_effort: { type: 'string', description: 'Step-level actual effort, free-form ("45m", "2h").' },
|
|
761
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
762
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
763
|
+
project: { type: 'string', description: 'Optional: name of a linked project to update the step in. Defaults to the current project.' },
|
|
764
|
+
},
|
|
765
|
+
required: ['planId', 'stepId'],
|
|
766
|
+
},
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
name: 'bclaw_delete_step',
|
|
770
|
+
description: 'Remove a sub-step from a plan. Requires contributor trust level or above. Pass `project` to operate on a plan in a linked project.',
|
|
771
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'prompt' },
|
|
772
|
+
inputSchema: {
|
|
773
|
+
type: 'object',
|
|
774
|
+
properties: {
|
|
775
|
+
planId: { type: 'string', description: 'Plan item ID.' },
|
|
776
|
+
stepId: { type: 'string', description: 'Step ID to delete.' },
|
|
777
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
778
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
779
|
+
project: { type: 'string', description: 'Optional: name of a linked project to delete the step from. Defaults to the current project.' },
|
|
780
|
+
},
|
|
781
|
+
required: ['planId', 'stepId'],
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
name: 'bclaw_delete_plan',
|
|
786
|
+
description: 'Delete a plan item by ID. Requires trusted or curator trust level.',
|
|
787
|
+
annotations: { tier: 'advanced', category: 'coordination', headlessApproval: 'prompt' },
|
|
788
|
+
inputSchema: {
|
|
789
|
+
type: 'object',
|
|
790
|
+
properties: {
|
|
791
|
+
id: { type: 'string', description: 'Plan item ID to delete.' },
|
|
792
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
793
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
794
|
+
},
|
|
795
|
+
required: ['id'],
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
name: 'bclaw_delete_sequence',
|
|
800
|
+
description: 'Delete a sequence by ID. Requires trusted or curator trust level.',
|
|
801
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'prompt' },
|
|
802
|
+
inputSchema: {
|
|
803
|
+
type: 'object',
|
|
804
|
+
properties: {
|
|
805
|
+
id: { type: 'string', description: 'Sequence ID to delete.' },
|
|
806
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
807
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
808
|
+
},
|
|
809
|
+
required: ['id'],
|
|
810
|
+
},
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
name: 'bclaw_delete_memory',
|
|
814
|
+
description: 'Delete a memory item (constraint, decision, or trap) by ID. Requires trusted or curator trust level.',
|
|
815
|
+
annotations: { tier: 'advanced', category: 'memory', headlessApproval: 'prompt' },
|
|
816
|
+
inputSchema: {
|
|
817
|
+
type: 'object',
|
|
818
|
+
properties: {
|
|
819
|
+
id: { type: 'string', description: 'ID of the item to delete.' },
|
|
820
|
+
type: { type: 'string', description: 'Item type: constraint, decision, trap.' },
|
|
821
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
822
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
823
|
+
},
|
|
824
|
+
required: ['id', 'type'],
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
name: 'bclaw_update_memory',
|
|
829
|
+
description: 'Update text, tags, or trap status of a constraint, decision, or trap by ID. Optionally move it to a different store level. Requires trusted or curator trust level.',
|
|
830
|
+
annotations: { tier: 'advanced', category: 'memory', headlessApproval: 'prompt' },
|
|
831
|
+
inputSchema: {
|
|
832
|
+
type: 'object',
|
|
833
|
+
properties: {
|
|
834
|
+
id: { type: 'string', description: 'ID of the item to update.' },
|
|
835
|
+
type: { type: 'string', description: 'Item type: constraint, decision, trap.' },
|
|
836
|
+
text: { type: 'string', description: 'New text (optional).' },
|
|
837
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'New tags (replaces existing).' },
|
|
838
|
+
status: { type: 'string', description: 'New status for traps: active, resolved, expired.' },
|
|
839
|
+
moveToStore: { type: 'string', description: 'Move item to a different store level: local, repo, workspace, user.' },
|
|
840
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
841
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
842
|
+
},
|
|
843
|
+
required: ['id', 'type'],
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
name: 'bclaw_add_capability',
|
|
848
|
+
description: 'Register a new project capability. Requires contributor trust level or above.',
|
|
849
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'prompt' },
|
|
850
|
+
inputSchema: {
|
|
851
|
+
type: 'object',
|
|
852
|
+
properties: {
|
|
853
|
+
name: { type: 'string', description: 'Capability name.' },
|
|
854
|
+
description: { type: 'string', description: 'Capability description.' },
|
|
855
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Additional tags.' },
|
|
856
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
857
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
858
|
+
},
|
|
859
|
+
required: ['name', 'description'],
|
|
860
|
+
},
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
name: 'bclaw_add_tool',
|
|
864
|
+
description: 'Register a new project tool. Requires contributor trust level or above.',
|
|
865
|
+
annotations: { tier: 'advanced', category: 'discovery', headlessApproval: 'prompt' },
|
|
866
|
+
inputSchema: {
|
|
867
|
+
type: 'object',
|
|
868
|
+
properties: {
|
|
869
|
+
name: { type: 'string', description: 'Tool name.' },
|
|
870
|
+
description: { type: 'string', description: 'Tool description.' },
|
|
871
|
+
type: { type: 'string', description: 'Tool type: workflow, validator, generator, utility, explorer (default: utility).' },
|
|
872
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Additional tags.' },
|
|
873
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
874
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
875
|
+
},
|
|
876
|
+
required: ['name', 'description'],
|
|
877
|
+
},
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
name: 'bclaw_correct_handoff',
|
|
881
|
+
description: 'Write a correction handoff that supersedes an earlier, incorrect one (P6.1 tombstone). The original handoff is left immutable — federation and history still carry both records. The new handoff copies non-overridden fields from the original and sets `supersedes` back at it; the original gets `superseded_by` pointing at the new record.',
|
|
882
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'prompt' },
|
|
883
|
+
inputSchema: {
|
|
884
|
+
type: 'object',
|
|
885
|
+
properties: {
|
|
886
|
+
originalId: { type: 'string', description: 'ID of the handoff to correct.' },
|
|
887
|
+
text: { type: 'string', description: 'Optional replacement narrative (markdown / free text). Defaults to the original narrative with an appended correction note.' },
|
|
888
|
+
narrative: { type: 'string', description: 'Optional override of the narrative sub-field.' },
|
|
889
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Optional replacement tags. Defaults to original tags.' },
|
|
890
|
+
reason: { type: 'string', description: 'Short rationale for the correction, appended to the narrative.' },
|
|
891
|
+
agent: { type: 'string', description: 'Author of the correction.' },
|
|
892
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
893
|
+
},
|
|
894
|
+
required: ['originalId'],
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
name: 'bclaw_update_handoff',
|
|
899
|
+
description: 'Update the status, recipient, contract, or review state of an open handoff. Requires contributor trust level or above. Use targetProject to push the resulting handoff state to a linked project.',
|
|
900
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
901
|
+
inputSchema: {
|
|
902
|
+
type: 'object',
|
|
903
|
+
properties: {
|
|
904
|
+
id: { type: 'string', description: 'Handoff ID to update.' },
|
|
905
|
+
targetProject: { type: 'string', description: 'Push the updated handoff as a cross-project signal to a linked project (name or path).' },
|
|
906
|
+
target_project: { type: 'string', description: 'Snake_case alias of targetProject.' },
|
|
907
|
+
status: { type: 'string', description: 'New status: open, closed.' },
|
|
908
|
+
to: { type: 'string', description: 'New recipient agent name.' },
|
|
909
|
+
files_touched: { type: 'array', items: { type: 'string' }, description: 'Files touched in this handoff.' },
|
|
910
|
+
pre_conditions: { type: 'array', items: { type: 'string' }, description: 'Pre-conditions for the receiving agent.' },
|
|
911
|
+
post_conditions: { type: 'array', items: { type: 'string' }, description: 'Post-conditions the receiving agent must satisfy.' },
|
|
912
|
+
tests_to_verify: { type: 'array', items: { type: 'string' }, description: 'Tests the receiving agent should verify.' },
|
|
913
|
+
linked_plans: { type: 'array', items: { type: 'string' }, description: 'Linked plan IDs.' },
|
|
914
|
+
narrative: { type: 'string', description: 'Free-text narrative of what happened and why, beyond the auto-generated commit list.' },
|
|
915
|
+
reviewer: { type: 'string', description: 'Assigned reviewer for the handoff review.' },
|
|
916
|
+
review_verdict: { type: 'string', enum: ['approve', 'request_changes'], description: 'Structured review verdict for this handoff.' },
|
|
917
|
+
reviewed_by: { type: 'string', description: 'Agent or reviewer who produced the verdict.' },
|
|
918
|
+
review_summary: { type: 'string', description: 'Short summary of the review outcome.' },
|
|
919
|
+
blocking_issues: { type: 'array', items: { type: 'string' }, description: 'Blocking issues raised by review.' },
|
|
920
|
+
suggestions: { type: 'array', items: { type: 'string' }, description: 'Non-blocking suggestions raised by review.' },
|
|
921
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
922
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
923
|
+
},
|
|
924
|
+
required: ['id'],
|
|
925
|
+
},
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
name: 'bclaw_compact',
|
|
929
|
+
description: 'LLM-driven semantic memory compaction (two-phase). Phase 1 (no args or assess=true): returns pressure assessment and compaction template listing eligible items. Phase 2 (archiveIds + optional newItems): archives specified items and creates new durable memory entries. Safety: creates a backup before archiving.',
|
|
930
|
+
annotations: { tier: 'advanced', category: 'memory', headlessApproval: 'prompt' },
|
|
931
|
+
inputSchema: {
|
|
932
|
+
type: 'object',
|
|
933
|
+
properties: {
|
|
934
|
+
assess: { type: 'boolean', description: 'Phase 1: return pressure assessment and compaction template. Default when no archiveIds provided.' },
|
|
935
|
+
archiveIds: { type: 'array', items: { type: 'string' }, description: 'Phase 2: IDs of items to archive (from assessment eligible list).' },
|
|
936
|
+
newItems: {
|
|
937
|
+
type: 'array',
|
|
938
|
+
items: {
|
|
939
|
+
type: 'object',
|
|
940
|
+
properties: {
|
|
941
|
+
type: { type: 'string', enum: ['constraint', 'decision', 'trap'], description: 'Memory item type.' },
|
|
942
|
+
text: { type: 'string', description: 'Content of the new memory item.' },
|
|
943
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Tags for the new item.' },
|
|
944
|
+
severity: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Severity (traps only). Default: medium.' },
|
|
945
|
+
},
|
|
946
|
+
required: ['type', 'text'],
|
|
947
|
+
},
|
|
948
|
+
description: 'Phase 2: new durable memory items from your compaction summaries.',
|
|
949
|
+
},
|
|
950
|
+
maxItems: { type: 'number', description: 'Max items to show in assessment. Default: 20.' },
|
|
951
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
952
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
953
|
+
},
|
|
954
|
+
},
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
name: 'bclaw_work',
|
|
958
|
+
description: 'Facade entry point: start a session, load context, and optionally claim a scope in a single call. intent=execute creates a claim; intent=consult/resume/review skips it. Eliminates the need for separate bclaw_session_start + bclaw_get_context + bclaw_claim calls.',
|
|
959
|
+
annotations: { tier: 'facade', category: 'session', headlessApproval: 'auto' },
|
|
960
|
+
inputSchema: {
|
|
961
|
+
type: 'object',
|
|
962
|
+
properties: {
|
|
963
|
+
intent: { type: 'string', enum: ['execute', 'consult', 'resume', 'review'], description: 'Work intent. "execute" creates a claim on the scope.' },
|
|
964
|
+
scope: { type: 'string', description: 'Scope being worked on (required for execute intent to create a claim).' },
|
|
965
|
+
planId: { type: 'string', description: 'Optional linked plan item ID.' },
|
|
966
|
+
task: { type: 'string', description: 'Optional task description (used as claim description when creating a claim).' },
|
|
967
|
+
messageId: { type: 'string', description: 'Optional message/thread ID for traceability.' },
|
|
968
|
+
contextTarget: { type: 'string', description: 'Optional path passed to bclaw_get_context to filter memory.' },
|
|
969
|
+
project: { type: 'string', description: 'Optional linked project name/path. Routes session, context, claims, audit, and bootstrap probe to that project. Defaults to the current cwd.' },
|
|
970
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
971
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
972
|
+
compact: { type: 'boolean', description: 'Return a compact payload (default true). Set to false to include the full context result. Compact mode avoids exceeding MCP token limits on projects with large memory.', default: true },
|
|
973
|
+
budget_tokens: { type: 'number', description: 'Approximate token budget for the context payload. Relevance-ranked fill: highest-scoring items kept until the budget is reached (~4 chars/token).' },
|
|
974
|
+
},
|
|
975
|
+
required: ['intent'],
|
|
976
|
+
},
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
name: 'bclaw_coordinate',
|
|
980
|
+
description: 'Multi-agent coordination facade: assign tasks to agents (with claims), consult agents (no claim), create a review candidate, open an ideation loop, reroute an active claim to another agent, or summarize a thread. Returns a FacadeResponse with selected_targets, delivery_plan, artifacts, side_effects, and execution_status. IMPORTANT — execution_status semantics: `delivered_and_started` means the spawn wrapper touched the brief-ack sentinel (`.brainclaw/coordination/runtime/ack/<assignment_id>.ack`) — NOT that the worker is doing useful work. Spawned workers may still die silently before consuming the brief (cf. trap trp_38f63ea4). To verify a dispatch is actually alive, call `bclaw_dispatch_status(target_id=<asgn_…>)` — it reads the runtime sentinels (ack/heartbeat/completed/failed) plus captured stdout/stderr tails and returns a single health verdict + recommended next action (this is the `verify_with` target attached to the response). Do NOT diagnose liveness from the tracked pid: on Windows an ack-wrapped spawn runs under cmd.exe, so `agent_run.pid` is the wrapper (which exits early by design), NOT the real worker — `Get-Process -Id <pid>` reads it dead while the worker is alive and committing. The reconciler trusts the sentinels and infers `completed` from a post-start commit even when the worker never called bclaw_assignment_update. See docs/concepts/dispatch-lifecycle.md for the full FSM + diagnostic decision tree, and docs/integrations/<agent>.md for per-agent spawn semantics (notably codex.md re sandbox MCP availability).',
|
|
981
|
+
annotations: { tier: 'facade', category: 'coordination', headlessApproval: 'auto' },
|
|
982
|
+
inputSchema: {
|
|
983
|
+
type: 'object',
|
|
984
|
+
properties: {
|
|
985
|
+
intent: { type: 'string', enum: ['assign', 'consult', 'review', 'reroute', 'summarize', 'ideate'], description: 'Coordination intent. assign/review/reroute and multi-agent ideate spawn worker processes; consult/summarize do not. "assign" creates a claim per target agent and spawns a worker on the brief. "consult" delivers the brief to the target inbox(es) WITHOUT creating claims and WITHOUT spawning — targets pick it up via their own bclaw_work. "review" creates a review candidate (and, with open_loop, a review loop). "ideate" opens an ideation loop with the task as the proposal seed; with targetAgents it advances to critique and SPAWNS one worktree-isolated critic worker per target (autoExecute honored, pln#626 Phase 2), otherwise it opens the loop for the champion to drive manually. "reroute" releases the current claim and reassigns. "summarize" reads a thread and returns a summary.' },
|
|
986
|
+
task: { type: 'string', description: 'Brief or task description delivered to target agents. TRANSPORT NOTE (dec#133): a spawned worker\'s capabilities follow its invoke template, not the mere presence of "sandbox". A sandboxed codex worker (`--sandbox workspace-write`, `approval_policy=never`) CAN reach brainclaw MCP — the server runs out-of-sandbox and every tool call is auto-approved — so MCP lifecycle calls (`bclaw_assignment_update`, `bclaw_send_message`, …) do NOT hang. Its one real limit is that `.git` is read-only: it cannot `git commit`, so it must leave fixes uncommitted in the worktree and the coordinator integrates + commits the diff at harvest (never instruct such a worker to commit). Genuinely MCP-less agents (nanoclaw/nemoclaw/picoclaw/zeroclaw) have no MCP at all: for them, prefer file-based protocols (write findings/reply to a markdown file in the worktree; the coordinator harvests it and lifecycle-closes the assignment). See docs/integrations/<agent>.md for the per-agent capability matrix.' },
|
|
987
|
+
scope: { type: 'string', description: 'File or feature scope. Used as claim scope for assign/reroute; as thread id for summarize if threadId is absent.' },
|
|
988
|
+
targetAgents: { type: 'array', items: { type: 'string' }, description: 'Agent names to target. If omitted, all spawnable agents are used.' },
|
|
989
|
+
constraints: { type: 'object', description: 'Optional structured constraints passed alongside the brief (e.g. deadline, reviewCriteria).' },
|
|
990
|
+
threadId: { type: 'string', description: 'Thread ID for summarize intent.' },
|
|
991
|
+
autoExecute: { type: 'boolean', description: 'Attempt to spawn target agents after delivery (default: true). Applies to the spawning intents assign/review/reroute AND to multi-agent ideate (with targetAgents, it spawns one worktree-isolated critic worker per target). consult is inbox-only and ignores autoExecute; summarize just reads a thread and ignores it. When false on a spawning intent, returns command_ready_manual with bash commands for the supervisor to run.' },
|
|
992
|
+
open_loop: { type: 'boolean', description: 'For intent=review only: also open a review Loop on top of the candidate (author + reviewer slots, advance to `findings`, dispatch turns). Default false — existing review callers are unaffected. See docs/concepts/loop-engine.md §Automation.' },
|
|
993
|
+
review_mode: { type: 'string', enum: ['asymmetric', 'symmetric'], description: 'Optional review Loop mode when open_loop=true. `asymmetric` (default) keeps the classical author→reviewer handoff; `symmetric` lets each reviewer turn also apply fixes directly, halving round-trips for spec/doc reviews. Ignored when open_loop is false.' },
|
|
994
|
+
preflight: { type: 'boolean', description: 'pln#533: when open_loop=true, run a trivial validation spawn per reviewer agent BEFORE opening the loop so an environment death (config rejected, auth fail, model mismatch) surfaces instantly with a clear reason instead of a generic loop timeout. Reviewers that fail pre-flight are dropped (with a targeted warning); if all fail, loop creation is skipped. Default true; set false to skip (e.g. you already ran `brainclaw doctor --spawn-check`). Ignored when open_loop is false or BRAINCLAW_NO_SPAWN is set.' },
|
|
995
|
+
client_request_id: { type: 'string', description: 'Caller-minted ULID/UUIDv7 for idempotent retries. Currently observed on intent="review" + open_loop=true: a retry with the same client_request_id returns the cached {candidate_id, loop_id} response instead of creating a duplicate candidate + loop. Safe to pass on other intents — silently ignored.' },
|
|
996
|
+
agent: { type: 'string', description: 'Caller agent name.' },
|
|
997
|
+
agentId: { type: 'string', description: 'Caller registered agent id.' },
|
|
998
|
+
project: { type: 'string', description: 'Optional (pln#359 phase 1b): name of a linked project to dispatch into. When set, claim/assignment/message all land in the target project — the target agent picks the brief up async via its own bclaw_work. Auto-spawn is disabled in cross-project mode. Accepts cross_project_links and workspace store-chain children (see `brainclaw link list`).' },
|
|
999
|
+
allow_dirty: { type: 'boolean', description: 'Override the scope-aware dirty-working-tree guard (trp#371 Tier 2). The guard runs only for worktree-spawning intents (assign/review/reroute) and blocks only when uncommitted files overlap — or cannot be proven disjoint from — the dispatch scope (the worker spawns from HEAD and will not see them). `.brainclaw/` and `.git/` are always excluded. Set true to proceed anyway (the block is downgraded to a warning that lists the overlapping files). Boolean; the string "true"/"false" are also coerced.' },
|
|
1000
|
+
ref: { type: 'string', description: 'Optional git ref (commit/branch/tag) for assign/review/reroute and multi-agent ideate: the dispatched worker (or ideate critic) builds its worktree from this ref instead of HEAD. When set, uncommitted working-tree changes are intentionally out of scope and the dirty guard allows the dispatch. Ignored by consult/summarize and single-agent ideate (no worktree).' },
|
|
1001
|
+
preset: { type: 'string', description: 'pln#511: loop preset selector — only valid with intent="ideate". When set, the handler bypasses the kind-default ideation phases and opens the loop with the named preset\'s phases / stop_condition / protocol. v1 ships a single preset: "bootstrap" (see src/core/loops/presets/). The name is validated against the preset registry: unknown names are rejected with `unknown_preset`; passing preset with any intent other than "ideate" is rejected with `preset_kind_mismatch` (presets are kind-specific).' },
|
|
1002
|
+
model: { type: 'string', description: 'Model to run on the spawned worker, decoupled from agent identity (e.g. "sonnet", "gpt-5-codex", "gpt-5.4"). Injected as `<model_flag> <model>` into the invoke command for agents that declare one (claude-code/codex/github-copilot); no-op for template-pinned pseudo-identities (e.g. claude-sonnet) or agents without a model_flag. Highest-priority link in the model resolution chain (override > lane > identity > default). Injected into the spawn command for the spawning intents (assign/review/reroute) and multi-agent ideate critics, and into the manual command hint for consult; ignored by summarize (which issues no command).' },
|
|
1003
|
+
},
|
|
1004
|
+
required: ['intent', 'task'],
|
|
1005
|
+
},
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
name: 'bclaw_loop',
|
|
1009
|
+
description: 'Loop engine facade: open/turn/complete_turn/advance/add_artifact/pause/resume/close/get/list multi-turn work loops (review, ideation, implementation, research, debug). Returns a FacadeResponse with the loop thread, the newly-appended event, and a next_expected hint describing the natural next intent. Experimental — schema may evolve; gate production callers behind MCP versioning (pln#392).',
|
|
1010
|
+
// schemaSource is informational for now — grep target so future migrators
|
|
1011
|
+
// can locate zod-derived tools quickly. The parity test in
|
|
1012
|
+
// tests/unit/mcp-zod-parity.test.ts hard-codes its (tool, zod-schema)
|
|
1013
|
+
// pairs explicitly; it does NOT enumerate by this annotation. If that
|
|
1014
|
+
// test ever moves to annotation-driven enrollment, validate the
|
|
1015
|
+
// annotation against a closed enum then. Sister guard: the hand-written
|
|
1016
|
+
// facade schemas (bclaw_work, bclaw_coordinate) are NOT zod-derived —
|
|
1017
|
+
// tests/unit/mcp-facade-structural-parity.test.ts asserts bidirectional
|
|
1018
|
+
// structural parity (keys + enums) between them and their zod request
|
|
1019
|
+
// schemas in src/core/facade-schema.ts (pln#622 PR0b).
|
|
1020
|
+
annotations: { tier: 'facade', category: 'loops', headlessApproval: 'auto', experimental: true, schemaSource: 'zod-derived' },
|
|
1021
|
+
inputSchema: {
|
|
1022
|
+
type: 'object',
|
|
1023
|
+
...(loopPhaseDefs ? { $defs: loopPhaseDefs } : {}),
|
|
1024
|
+
properties: {
|
|
1025
|
+
intent: {
|
|
1026
|
+
type: 'string',
|
|
1027
|
+
// 'open' is intentionally NOT exposed standalone (pln#542): it
|
|
1028
|
+
// created a loop structure without dispatching the first turn, so
|
|
1029
|
+
// nothing ever ran. Loops are opened via
|
|
1030
|
+
// bclaw_coordinate(intent='review', open_loop=true) or intent='ideate'.
|
|
1031
|
+
enum: ['get', 'list', 'turn', 'complete_turn', 'advance', 'add_artifact', 'pause', 'resume', 'close'],
|
|
1032
|
+
description: 'Loop lifecycle intent for driving turns inside a loop that was already opened via the coordinate facade. To START a loop, use `bclaw_coordinate(intent="review", open_loop=true, targetAgents=[…])` or `intent="ideate"` — that opens the loop AND dispatches the first turn. See docs/concepts/loop-engine.md.',
|
|
1033
|
+
},
|
|
1034
|
+
loop_id: { type: 'string', description: 'Target loop id (lop_…). Required for every intent except open and list.' },
|
|
1035
|
+
kind: { type: 'string', enum: ['review', 'ideation', 'implementation', 'research', 'debug'], description: 'Loop kind for open / list filter.' },
|
|
1036
|
+
title: { type: 'string', description: 'Human-readable title (open).' },
|
|
1037
|
+
goal: { type: 'string', description: 'Optional goal statement (open).' },
|
|
1038
|
+
phases: { type: 'array', items: loopPhaseItemSchema, description: 'Optional phase list override (open). Items derived from LoopPhaseSchema (zod source) — see mcp-schemas.generated.ts.' },
|
|
1039
|
+
slots: { type: 'array', items: loopSlotInputItemSchema, description: 'Optional initial slot specs (open). Items derived from LoopSlotInputSchema (zod source). Each item carries at least { role }.' },
|
|
1040
|
+
linked: { type: 'object', description: 'Optional top-level plan/sequence refs (open).' },
|
|
1041
|
+
stop_condition: { type: 'object', description: 'Optional stop_condition override (open). Composite any/all supported.' },
|
|
1042
|
+
mode: { type: 'string', enum: ['asymmetric', 'symmetric'], description: 'Review mode selector for open (review kind only).' },
|
|
1043
|
+
status: { type: 'string', description: 'For intent="list": filter value (any loop status). For intent="close": target final status — accepted values are `completed` | `cancelled` | `blocked` only (NOT `failed`; map crashed/dead loops to `cancelled` with a `reason`).' },
|
|
1044
|
+
include_events: { type: 'boolean', description: 'get: include the event journal in the response.' },
|
|
1045
|
+
limit: { type: 'number', description: 'list: max loops returned.' },
|
|
1046
|
+
offset: { type: 'number', description: 'list: pagination offset.' },
|
|
1047
|
+
slot_id: { type: 'string', description: 'Slot id for turn / complete_turn.' },
|
|
1048
|
+
role: { type: 'string', description: 'Slot role for turn (resolves the first non-done slot with that role).' },
|
|
1049
|
+
input: { type: 'string', description: 'turn: free-form input passed to the slot.' },
|
|
1050
|
+
assignment_id: { type: 'string', description: 'turn: assignment id produced by the dispatcher to be recorded on the slot.' },
|
|
1051
|
+
dispatch: { type: 'boolean', description: 'turn: whether the caller has already dispatched the downstream work (recorded for auditability; no spawn happens here).' },
|
|
1052
|
+
outcome: { type: 'string', enum: ['done', 'failed', 'cancelled'], description: 'complete_turn outcome (default done).' },
|
|
1053
|
+
failure_reason: { type: 'string', description: 'complete_turn: optional failure/cancel reason.' },
|
|
1054
|
+
artifact: { type: 'object', description: 'complete_turn / add_artifact payload: { phase, type, body?, produced_by?, ref? }.' },
|
|
1055
|
+
to_phase: { type: 'string', description: 'advance: explicit target phase (otherwise the next phase).' },
|
|
1056
|
+
force: { type: 'boolean', description: 'advance: allow going backwards (increments iteration_count).' },
|
|
1057
|
+
reason: { type: 'string', description: 'advance / pause / close: optional reason string.' },
|
|
1058
|
+
expected_version: { type: 'number', description: 'Accepted for RFC compatibility on mutating intents, but not enforced until lock/CAS wiring lands.' },
|
|
1059
|
+
client_request_id: { type: 'string', description: 'Accepted for RFC compatibility on mutating intents, but not enforced until lock/idempotency wiring lands.' },
|
|
1060
|
+
project: { type: 'string', description: 'Optional linked project name/path. Routes loop reads and mutations to that project. Defaults to the current cwd.' },
|
|
1061
|
+
agent: { type: 'string', description: 'Caller agent name.' },
|
|
1062
|
+
agentId: { type: 'string', description: 'Caller registered agent id (enforced for slot-bound auth in complete_turn).' },
|
|
1063
|
+
},
|
|
1064
|
+
required: ['intent'],
|
|
1065
|
+
},
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
name: 'bclaw_assignment_update',
|
|
1069
|
+
description: 'Report assignment lifecycle status. Part of the Agent SDK runtime protocol. Workers call this to report: accepted (acknowledging receipt), started (work begun), progress (heartbeat), completed (done with artifacts), failed (error), or blocked (external blocker). The assignment_id is provided in the dispatch brief. OWNERSHIP (trp#291): only the agent the assignment is OWNED BY (the dispatched worker) may update it — a different agent (e.g. the coordinator) gets `Agent <x> cannot update assignment owned by <y>`. If you are the coordinator and need to converge a worker run, do NOT call this; verify via bclaw_dispatch_status instead (the reconciler infers completion from sentinels/commits).',
|
|
1070
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
1071
|
+
inputSchema: {
|
|
1072
|
+
type: 'object',
|
|
1073
|
+
properties: {
|
|
1074
|
+
assignment_id: { type: 'string', description: 'Assignment ID from the dispatch brief (asgn_xxx).' },
|
|
1075
|
+
status: { type: 'string', enum: ['accepted', 'started', 'progress', 'completed', 'failed', 'blocked'], description: 'Lifecycle status to report.' },
|
|
1076
|
+
message: { type: 'string', description: 'Human-readable status message or progress note.' },
|
|
1077
|
+
artifacts: {
|
|
1078
|
+
type: 'array',
|
|
1079
|
+
items: {
|
|
1080
|
+
type: 'object',
|
|
1081
|
+
properties: {
|
|
1082
|
+
type: { type: 'string', description: 'Artifact type: commit, branch, file, pr, test_result.' },
|
|
1083
|
+
ref: { type: 'string', description: 'Reference: SHA, branch name, file path, PR URL.' },
|
|
1084
|
+
description: { type: 'string', description: 'Optional description.' },
|
|
1085
|
+
},
|
|
1086
|
+
required: ['type', 'ref'],
|
|
1087
|
+
},
|
|
1088
|
+
description: 'Artifacts produced. Most useful for completed status.',
|
|
1089
|
+
},
|
|
1090
|
+
error_message: { type: 'string', description: 'Error details (for failed status).' },
|
|
1091
|
+
blocker: { type: 'string', description: 'Blocker description (for blocked status).' },
|
|
1092
|
+
action_required: {
|
|
1093
|
+
type: 'object',
|
|
1094
|
+
description: 'Optional ActionRequired payload when status=blocked. Lets the worker request approval, user input, or clarification before resuming.',
|
|
1095
|
+
properties: {
|
|
1096
|
+
kind: { type: 'string', enum: ['approval', 'user_input', 'clarification', 'plan_approval'], description: 'Kind of action needed.' },
|
|
1097
|
+
title: { type: 'string', description: 'Short title shown to supervisors/UI.' },
|
|
1098
|
+
prompt: { type: 'string', description: 'Question or approval prompt to answer.' },
|
|
1099
|
+
options: { type: 'array', items: { type: 'string' }, description: 'Optional answer choices.' },
|
|
1100
|
+
response_schema: { type: 'object', description: 'Optional structured response schema hint.' },
|
|
1101
|
+
tags: { type: 'array', items: { type: 'string' }, description: 'Optional tags.' },
|
|
1102
|
+
},
|
|
1103
|
+
required: ['kind', 'title', 'prompt'],
|
|
1104
|
+
},
|
|
1105
|
+
agent: { type: 'string', description: 'Agent name.' },
|
|
1106
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
1107
|
+
},
|
|
1108
|
+
required: ['assignment_id', 'status'],
|
|
1109
|
+
},
|
|
1110
|
+
},
|
|
1111
|
+
{
|
|
1112
|
+
name: 'bclaw_assignment_action',
|
|
1113
|
+
description: 'Resolve or reject a pending ActionRequired item and update the linked Assignment/AgentRun state.',
|
|
1114
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
1115
|
+
inputSchema: {
|
|
1116
|
+
type: 'object',
|
|
1117
|
+
properties: {
|
|
1118
|
+
action_id: { type: 'string', description: 'ActionRequired ID (act_xxx).' },
|
|
1119
|
+
outcome: { type: 'string', enum: ['resolved', 'rejected', 'cancelled'], description: 'How the supervisor resolves the pending action.' },
|
|
1120
|
+
text: { type: 'string', description: 'Human-readable response or rationale.' },
|
|
1121
|
+
payload: { type: 'object', description: 'Optional structured response payload.' },
|
|
1122
|
+
agent: { type: 'string', description: 'Supervisor/agent responding to the action.' },
|
|
1123
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
1124
|
+
},
|
|
1125
|
+
required: ['action_id', 'outcome'],
|
|
1126
|
+
},
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
name: 'bclaw_harvest_candidates',
|
|
1130
|
+
description: 'Harvest candidates from worktree inboxes into the main project store. Use this as the coordinator-side bridge for agents running under --sandbox workspace-write (e.g. Codex), which cannot write to the main store via MCP and instead write to their worktree .brainclaw/coordination/inbox/. Requires trusted trust level.',
|
|
1131
|
+
annotations: { tier: 'standard', category: 'coordination', headlessApproval: 'auto' },
|
|
1132
|
+
inputSchema: {
|
|
1133
|
+
type: 'object',
|
|
1134
|
+
properties: {
|
|
1135
|
+
worktreePaths: { type: 'array', items: { type: 'string' }, description: 'Explicit worktree paths to scan. Defaults to all active worktrees under ~/.brainclaw/worktrees/<project-hash>/.' },
|
|
1136
|
+
dryRun: { type: 'boolean', description: 'When true, report what would be harvested without writing anything.' },
|
|
1137
|
+
agent: { type: 'string', description: 'Coordinator agent name for runtime event attribution.' },
|
|
1138
|
+
agentId: { type: 'string', description: 'Registered agent id.' },
|
|
1139
|
+
},
|
|
1140
|
+
required: [],
|
|
1141
|
+
},
|
|
1142
|
+
},
|
|
1143
|
+
// ── Canonical CRUD verbs (Phase 3 / v1.0 grammar) ──────────────────
|
|
1144
|
+
// Promoted to `standard` tier at the v1.0 cut.
|
|
1145
|
+
{
|
|
1146
|
+
name: 'bclaw_find',
|
|
1147
|
+
description: 'Canonical list query over a brainclaw entity. Default read filter excludes records with provenance.kind="legacy" and auto_reflect records below 0.6 confidence — override via filter.includeLegacy / filter.minAutoReflectConfidence. Tag filters accept `tag: string` for one tag or `tags: string[]` for any-match. For entity="agent_run", filters also accept assignment_id, claim_id, and message_id. Pass `project` to query a linked project instead of the current one. PAGINATION & SIZE (pln#491): returns at most filter.limit items (default 50), and the page is additionally shrunk if it would exceed the MCP size budget. The response carries `total` (full match count), `returned`, and — when more remain — `has_more: true`, `next_offset`, and a `hint`; pass `filter.offset=<next_offset>` (or a narrower filter) to page rather than expecting everything at once. ORDERING: results follow on-disk/load order, NOT recency — do not assume the first item is the newest (trp#291); filter explicitly (e.g. status, plan_id) to target what you need.',
|
|
1148
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'auto' },
|
|
1149
|
+
inputSchema: {
|
|
1150
|
+
type: 'object',
|
|
1151
|
+
properties: {
|
|
1152
|
+
entity: { type: 'string', description: 'Entity name: plan | decision | constraint | trap | handoff | runtime_note | candidate | sequence | claim | action | assignment | agent_run | agent (read-only, redacted projection) | cross_project_link. Others not yet wired.' },
|
|
1153
|
+
filter: { type: 'object', description: 'Filter keys (ANY entity): status, tag (single tag), tags (array, any-match), author, plan_id, source, auto_generated, limit, offset, includeLegacy (bool, default false), minAutoReflectConfidence (0-1, default 0.6). ENTITY-SCOPED keys (rejected with a validation_error if used with any other entity): assignment_id, claim_id, message_id — ONLY for entity="agent_run"; scope ("project" default | "global", the latter unions the dispatchable catalog + adds dispatchable/registered) and includeReputation (bool — attaches a public reputation summary per agent) — ONLY for entity="agent". Unknown/mis-scoped keys are rejected loudly.' },
|
|
1154
|
+
project: { type: 'string', description: 'Optional: name (or path/basename) of a linked project to query. Defaults to the current project. Only cross_project_links (config.yaml) and workspace store-chain children are accepted — list with `brainclaw link list`.' },
|
|
1155
|
+
budget_tokens: { type: 'number', description: 'Optional token budget for the page payload (~4 chars/token). Tightens the default size cap; pagination metadata (has_more/next_offset) still applies.' },
|
|
1156
|
+
},
|
|
1157
|
+
required: ['entity'],
|
|
1158
|
+
},
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
name: 'bclaw_get',
|
|
1162
|
+
description: 'Fetch a single brainclaw entity by id or short_label. Pass `project` to fetch from a linked project instead of the current one.',
|
|
1163
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'auto' },
|
|
1164
|
+
inputSchema: {
|
|
1165
|
+
type: 'object',
|
|
1166
|
+
properties: {
|
|
1167
|
+
entity: { type: 'string', description: 'Entity name.' },
|
|
1168
|
+
id: { type: 'string', description: 'Entity id (e.g. dec_ab12cd) or short_label (e.g. dec#42).' },
|
|
1169
|
+
project: { type: 'string', description: 'Optional: name of a linked project to fetch from. Defaults to the current project. See `brainclaw link list` for accepted names.' },
|
|
1170
|
+
budget_tokens: { type: 'number', description: 'Optional token budget (~4 chars/token). Bounds unbounded fields (e.g. handoff snapshot diffs).' },
|
|
1171
|
+
},
|
|
1172
|
+
required: ['entity', 'id'],
|
|
1173
|
+
},
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
name: 'bclaw_create',
|
|
1177
|
+
description: 'Create a new brainclaw entity. Data fields are entity-specific; see src/core/schema.ts. Pass `project` to create in a linked project instead of the current one.',
|
|
1178
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'prompt' },
|
|
1179
|
+
inputSchema: {
|
|
1180
|
+
type: 'object',
|
|
1181
|
+
properties: {
|
|
1182
|
+
entity: { type: 'string', description: 'Entity name.' },
|
|
1183
|
+
data: { type: 'object', description: 'Create payload (e.g. { text, author, tags }).' },
|
|
1184
|
+
project: { type: 'string', description: 'Optional: name of a linked project to create the entity in. Defaults to the current project. Identity (author/agent) is resolved from the source registry — no need to be registered in the target.' },
|
|
1185
|
+
},
|
|
1186
|
+
required: ['entity', 'data'],
|
|
1187
|
+
},
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
name: 'bclaw_update',
|
|
1191
|
+
description: 'Partial update of mutable fields. Fields not in EntityRegistry.updatable are rejected — use bclaw_transition for status changes. Pass `project` to update an entity in a linked project instead of the current one.',
|
|
1192
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'prompt' },
|
|
1193
|
+
inputSchema: {
|
|
1194
|
+
type: 'object',
|
|
1195
|
+
properties: {
|
|
1196
|
+
entity: { type: 'string', description: 'Entity name.' },
|
|
1197
|
+
id: { type: 'string', description: 'Entity id.' },
|
|
1198
|
+
patch: { type: 'object', description: 'Fields to update (subset of EntityRegistry.updatable).' },
|
|
1199
|
+
project: { type: 'string', description: 'Optional: name of a linked project to update the entity in. Defaults to the current project.' },
|
|
1200
|
+
},
|
|
1201
|
+
required: ['entity', 'id', 'patch'],
|
|
1202
|
+
},
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
name: 'bclaw_remove',
|
|
1206
|
+
description: 'Remove a brainclaw entity. Archives by default; pass purge:true to hard-delete where supported. Pass `project` to remove from a linked project instead of the current one.',
|
|
1207
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'prompt' },
|
|
1208
|
+
inputSchema: {
|
|
1209
|
+
type: 'object',
|
|
1210
|
+
properties: {
|
|
1211
|
+
entity: { type: 'string', description: 'Entity name.' },
|
|
1212
|
+
id: { type: 'string', description: 'Entity id.' },
|
|
1213
|
+
purge: { type: 'boolean', description: 'Hard-delete instead of archive. Default false.' },
|
|
1214
|
+
project: { type: 'string', description: 'Optional: name of a linked project to remove the entity from. Defaults to the current project.' },
|
|
1215
|
+
},
|
|
1216
|
+
required: ['entity', 'id'],
|
|
1217
|
+
},
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
name: 'bclaw_transition',
|
|
1221
|
+
description: 'Transition an entity to a new status. Validated against EntityRegistry.transitions. Returns the triggered side-effect tags. Pass `project` to transition an entity in a linked project instead of the current one. For entity="claim": released/stale transitions are ownership-checked — non-owners must pass coordinator_override:true (trusted+ trust level required).',
|
|
1222
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'prompt' },
|
|
1223
|
+
inputSchema: {
|
|
1224
|
+
type: 'object',
|
|
1225
|
+
properties: {
|
|
1226
|
+
entity: { type: 'string', description: 'Entity name.' },
|
|
1227
|
+
id: { type: 'string', description: 'Entity id.' },
|
|
1228
|
+
to: { type: 'string', description: 'Target status.' },
|
|
1229
|
+
reason: { type: 'string', description: 'Optional free-text reason, audited alongside the transition.' },
|
|
1230
|
+
project: { type: 'string', description: 'Optional: name of a linked project to transition the entity in. Defaults to the current project.' },
|
|
1231
|
+
coordinator_override: { type: 'boolean', description: 'entity="claim" only: opt-in override for a trusted+ caller releasing/staling a claim they do NOT own. Audited when used. trp#928.' },
|
|
1232
|
+
},
|
|
1233
|
+
required: ['entity', 'id', 'to'],
|
|
1234
|
+
},
|
|
1235
|
+
},
|
|
1236
|
+
{
|
|
1237
|
+
name: 'bclaw_move',
|
|
1238
|
+
description: 'Relocate a brainclaw item to another project in a multi-project workspace, PRESERVING its id (so pln#/dec# references stay stable). Relocatable entities: plan, decision, constraint, trap, handoff, sequence. Execution-local entities (claim, assignment, agent_run, session) are NOT relocatable — they stay in the project where the work ran. Refuses on id collision in the target, a missing source, or an active claim on the item (unless force). Audits both stores.',
|
|
1239
|
+
annotations: { tier: 'standard', category: 'memory', headlessApproval: 'prompt' },
|
|
1240
|
+
inputSchema: {
|
|
1241
|
+
type: 'object',
|
|
1242
|
+
properties: {
|
|
1243
|
+
entity: { type: 'string', description: 'Entity name (plan, decision, constraint, trap, handoff, sequence).' },
|
|
1244
|
+
id: { type: 'string', description: 'Entity id to move.' },
|
|
1245
|
+
to_project: { type: 'string', description: 'Target project: name, path, or basename.' },
|
|
1246
|
+
from_project: { type: 'string', description: 'Source project (defaults to the current project).' },
|
|
1247
|
+
force: { type: 'boolean', description: 'Move even if an active claim references the item. Default false.' },
|
|
1248
|
+
},
|
|
1249
|
+
required: ['entity', 'id', 'to_project'],
|
|
1250
|
+
},
|
|
1251
|
+
},
|
|
1252
|
+
];
|
|
1253
|
+
/**
|
|
1254
|
+
* Combined catalog of every brainclaw MCP tool descriptor (read + write).
|
|
1255
|
+
* Exposed so tests can iterate inputSchemas (e.g. mcp-input-schema-strict.test.ts
|
|
1256
|
+
* runs ajv strict over each entry to prevent Copilot/Cursor-incompatible drift —
|
|
1257
|
+
* see trp#180 + pln#494).
|
|
1258
|
+
*/
|
|
1259
|
+
export const ALL_TOOLS = [...MCP_READ_TOOLS, ...MCP_WRITE_TOOLS];
|
|
1260
|
+
/**
|
|
1261
|
+
* Canonical list of all brainclaw MCP tool names, derived from ALL_TOOLS.
|
|
1262
|
+
* Source-of-truth consumed by agent integration writers (agent-files.ts)
|
|
1263
|
+
* to emit per-tool approval entries for each agent surface: Cline
|
|
1264
|
+
* `autoApprove`, Roo `alwaysAllow`, Codex `approval_mode`, etc. When a new
|
|
1265
|
+
* tool is registered in MCP_READ_TOOLS or MCP_WRITE_TOOLS it automatically
|
|
1266
|
+
* propagates here — no manual catalog sync required.
|
|
1267
|
+
*/
|
|
1268
|
+
export const MCP_TOOL_NAMES = ALL_TOOLS.map((tool) => tool.name);
|
|
1269
|
+
/**
|
|
1270
|
+
* Subset of MCP_TOOL_NAMES for tools that are safe for headless auto-approval.
|
|
1271
|
+
* Excludes dispatch, architectural gates (accept/reject), plan creation, setup,
|
|
1272
|
+
* switch, bootstrap, memory deletes, and other operations that warrant human review.
|
|
1273
|
+
* Consumed by agent-files writers (Cline autoApprove, Roo alwaysAllow, Codex approval_mode).
|
|
1274
|
+
*/
|
|
1275
|
+
export const MCP_HEADLESS_AUTO_TOOL_NAMES = ALL_TOOLS
|
|
1276
|
+
.filter((tool) => tool.annotations?.headlessApproval === 'auto')
|
|
1277
|
+
.map((tool) => tool.name);
|
|
1278
|
+
/**
|
|
1279
|
+
* Narrow "canonical grammar" tool set — the read-side facade entries
|
|
1280
|
+
* (session + context) plus the five memory verbs (find / get / create /
|
|
1281
|
+
* update / transition). Consumed by writers (e.g. Hermes' tools.include)
|
|
1282
|
+
* that want a minimal advertised surface rather than the full headless-auto
|
|
1283
|
+
* catalog. Coordination facades (dispatch, coordinate, loop) are excluded
|
|
1284
|
+
* because narrow-surface agents shouldn't be routing work.
|
|
1285
|
+
*
|
|
1286
|
+
* Derivation rule (no hand-curated array):
|
|
1287
|
+
* - tier=facade AND category in {session, context} AND headlessApproval=auto
|
|
1288
|
+
* - OR name in the canonical memory verbs
|
|
1289
|
+
*
|
|
1290
|
+
* Adding a new memory grammar verb is the only edit that requires touching
|
|
1291
|
+
* this file; everything else propagates from ALL_TOOLS annotations (pln#546 step 2).
|
|
1292
|
+
*/
|
|
1293
|
+
const _CANONICAL_GRAMMAR_MEMORY_VERBS = new Set([
|
|
1294
|
+
'bclaw_find',
|
|
1295
|
+
'bclaw_get',
|
|
1296
|
+
'bclaw_create',
|
|
1297
|
+
'bclaw_update',
|
|
1298
|
+
'bclaw_transition',
|
|
1299
|
+
]);
|
|
1300
|
+
export const MCP_CANONICAL_GRAMMAR_TOOL_NAMES = ALL_TOOLS
|
|
1301
|
+
.filter((tool) => {
|
|
1302
|
+
const ann = tool.annotations ?? {};
|
|
1303
|
+
if (ann.tier === 'facade'
|
|
1304
|
+
&& (ann.category === 'session' || ann.category === 'context')
|
|
1305
|
+
&& ann.headlessApproval === 'auto') {
|
|
1306
|
+
return true;
|
|
1307
|
+
}
|
|
1308
|
+
return _CANONICAL_GRAMMAR_MEMORY_VERBS.has(tool.name);
|
|
1309
|
+
})
|
|
1310
|
+
.map((tool) => tool.name);
|
|
1311
|
+
/**
|
|
1312
|
+
* Tools removed from the MCP surface at the v1.0 cut (Phase 3 slice 3i).
|
|
1313
|
+
* Handlers remain in place defensively, but these names are hidden from
|
|
1314
|
+
* every `tools/list` response — including `catalog: "all"`. Callers
|
|
1315
|
+
* should migrate to the canonical grammar (see
|
|
1316
|
+
* `docs/mcp-schema-changelog.md` 1.0.0 block for the full replacement
|
|
1317
|
+
* map).
|
|
1318
|
+
*/
|
|
1319
|
+
export const REMOVED_IN_V1_TOOLS = new Set([
|
|
1320
|
+
'bclaw_list_plans',
|
|
1321
|
+
'bclaw_list_candidates',
|
|
1322
|
+
'bclaw_list_claims',
|
|
1323
|
+
'bclaw_list_actions',
|
|
1324
|
+
'bclaw_list_assignments',
|
|
1325
|
+
'bclaw_list_runs',
|
|
1326
|
+
// pln#625 — the last surviving bclaw_list_* tool. Retired in favour of
|
|
1327
|
+
// bclaw_find(entity='agent'), which now carries the redacted projection AND
|
|
1328
|
+
// the includeReputation join. Handler stays as a redirect escape-hatch.
|
|
1329
|
+
'bclaw_list_agents',
|
|
1330
|
+
'bclaw_read_handoff',
|
|
1331
|
+
'bclaw_create_plan',
|
|
1332
|
+
'bclaw_update_plan',
|
|
1333
|
+
'bclaw_create_candidate',
|
|
1334
|
+
'bclaw_accept',
|
|
1335
|
+
'bclaw_reject',
|
|
1336
|
+
'bclaw_get_execution_context',
|
|
1337
|
+
'bclaw_get_agent_board',
|
|
1338
|
+
'bclaw_get_agent_board_summary',
|
|
1339
|
+
'bclaw_dispatch_analysis',
|
|
1340
|
+
'bclaw_dispatch_review',
|
|
1341
|
+
'bclaw_update_handoff',
|
|
1342
|
+
'bclaw_get_context',
|
|
1343
|
+
]);
|
|
1344
|
+
export const LEGACY_READ_TOOL_HANDLERS = new Set([
|
|
1345
|
+
'bclaw_get_context',
|
|
1346
|
+
'bclaw_get_execution_context',
|
|
1347
|
+
'bclaw_get_agent_board',
|
|
1348
|
+
'bclaw_get_agent_board_summary',
|
|
1349
|
+
'bclaw_list_plans',
|
|
1350
|
+
'bclaw_list_candidates',
|
|
1351
|
+
'bclaw_list_claims',
|
|
1352
|
+
'bclaw_list_actions',
|
|
1353
|
+
'bclaw_list_assignments',
|
|
1354
|
+
'bclaw_list_runs',
|
|
1355
|
+
'bclaw_list_agents',
|
|
1356
|
+
'bclaw_read_handoff',
|
|
1357
|
+
]);
|
|
1358
|
+
/** All tools minus the v1.0 removal set. Used by every tools/list branch and governance guards. */
|
|
1359
|
+
export const PUBLISHED_TOOLS = ALL_TOOLS.filter((tool) => !REMOVED_IN_V1_TOOLS.has(tool.name));
|
|
1360
|
+
/**
|
|
1361
|
+
* Canonical facade order — drives what a fresh agent sees first in tools/list.
|
|
1362
|
+
*
|
|
1363
|
+
* Mental model for the default agent (doing its own work, not orchestrating):
|
|
1364
|
+
* 1. bclaw_work — entry point: session + context + claim in one call.
|
|
1365
|
+
* 2. bclaw_context — explicit memory read when bclaw_work isn't enough.
|
|
1366
|
+
* 3. bclaw_coordinate / bclaw_dispatch / bclaw_loop — ESCALATION path for
|
|
1367
|
+
* agents that need to assign work, dispatch other agents, or drive
|
|
1368
|
+
* multi-turn loops. Optional for most sessions.
|
|
1369
|
+
* 4. bclaw_setup — one-time interactive onboarding.
|
|
1370
|
+
*
|
|
1371
|
+
* The typical working loop is: bclaw_work → canonical grammar
|
|
1372
|
+
* (bclaw_find/get/create/update/remove/transition) → bclaw_release_claim.
|
|
1373
|
+
* Coordination facades are not the default path.
|
|
1374
|
+
* (pln#397 + Codex audit P2, refined after user feedback on orchestration bias.)
|
|
1375
|
+
*/
|
|
1376
|
+
export const FACADE_ORDER = [
|
|
1377
|
+
'bclaw_work',
|
|
1378
|
+
'bclaw_context',
|
|
1379
|
+
'bclaw_coordinate',
|
|
1380
|
+
'bclaw_dispatch',
|
|
1381
|
+
'bclaw_dispatch_status',
|
|
1382
|
+
'bclaw_loop',
|
|
1383
|
+
'bclaw_setup',
|
|
1384
|
+
];
|
|
1385
|
+
function tierRank(tool) {
|
|
1386
|
+
const tier = tool.annotations?.tier;
|
|
1387
|
+
if (tier === 'facade')
|
|
1388
|
+
return 0;
|
|
1389
|
+
if (tier === 'standard')
|
|
1390
|
+
return 1;
|
|
1391
|
+
return 2; // advanced or missing
|
|
1392
|
+
}
|
|
1393
|
+
function facadePositionalRank(name) {
|
|
1394
|
+
const idx = FACADE_ORDER.indexOf(name);
|
|
1395
|
+
return idx >= 0 ? idx : Number.POSITIVE_INFINITY;
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Tools with tier facade or standard — returned by default. Advanced tools
|
|
1399
|
+
* require catalog=all. Sort rules (pln#397 Codex P2):
|
|
1400
|
+
* 1. tier: facade first, then standard.
|
|
1401
|
+
* 2. inside facades: FACADE_ORDER puts work/coordinate/context/dispatch/loop/setup
|
|
1402
|
+
* at the head — the sequence a new agent should learn in.
|
|
1403
|
+
* 3. inside standards: original declaration order (stable-sort fallback via index).
|
|
1404
|
+
*/
|
|
1405
|
+
export const DEFAULT_PUBLISHED_TOOLS = PUBLISHED_TOOLS
|
|
1406
|
+
.filter((tool) => {
|
|
1407
|
+
const tier = tool.annotations?.tier;
|
|
1408
|
+
return tier === 'facade' || tier === 'standard';
|
|
1409
|
+
})
|
|
1410
|
+
.map((tool, index) => ({ tool, index }))
|
|
1411
|
+
.sort((a, b) => {
|
|
1412
|
+
const tierDiff = tierRank(a.tool) - tierRank(b.tool);
|
|
1413
|
+
if (tierDiff !== 0)
|
|
1414
|
+
return tierDiff;
|
|
1415
|
+
if (tierRank(a.tool) === 0) {
|
|
1416
|
+
const pos = facadePositionalRank(a.tool.name) - facadePositionalRank(b.tool.name);
|
|
1417
|
+
if (pos !== 0)
|
|
1418
|
+
return pos;
|
|
1419
|
+
}
|
|
1420
|
+
return a.index - b.index;
|
|
1421
|
+
})
|
|
1422
|
+
.map(({ tool }) => tool);
|
|
1423
|
+
/**
|
|
1424
|
+
* Minimal catalog served while the project memory at cwd is absent.
|
|
1425
|
+
* Instead of refusing to boot (the historical exit(1)), the server starts
|
|
1426
|
+
* in "setup mode" so an agent landing on a fresh repo can initialize it
|
|
1427
|
+
* via bclaw_setup without a CLI shell-out + session-reload discontinuity.
|
|
1428
|
+
*/
|
|
1429
|
+
export const UNINITIALIZED_TOOL_NAMES = new Set([
|
|
1430
|
+
'bclaw_setup',
|
|
1431
|
+
'bclaw_init_project',
|
|
1432
|
+
'bclaw_doctor',
|
|
1433
|
+
]);
|
|
1434
|
+
export const UNINITIALIZED_PUBLISHED_TOOLS = PUBLISHED_TOOLS.filter((tool) => UNINITIALIZED_TOOL_NAMES.has(tool.name));
|
|
1435
|
+
export function buildUninitializedStateMessage(cwd) {
|
|
1436
|
+
return `Project memory not initialized at ${cwd}. The brainclaw MCP server is running in setup mode: only bclaw_setup, bclaw_init_project and bclaw_doctor are available. Call bclaw_setup to initialize this repo — the full tool catalog activates automatically afterwards.`;
|
|
1437
|
+
}
|
|
1438
|
+
//# sourceMappingURL=mcp-catalog.js.map
|