brainclaw 1.9.0 → 1.9.1
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 +585 -499
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/commands/harvest.js +1 -1
- package/dist/commands/hooks.js +73 -73
- package/dist/commands/init.js +1 -1
- package/dist/commands/install-hooks.js +78 -78
- package/dist/commands/mcp-read-handlers.js +57 -14
- package/dist/commands/mcp.js +79 -13
- package/dist/commands/switch.js +26 -5
- package/dist/commands/version.js +1 -1
- package/dist/core/agent-capability.js +19 -4
- package/dist/core/agent-files.js +119 -119
- package/dist/core/codev-prompts.js +38 -38
- package/dist/core/default-profiles/doctor.yaml +11 -11
- package/dist/core/default-profiles/janitor.yaml +11 -11
- package/dist/core/default-profiles/onboarder.yaml +11 -11
- package/dist/core/default-profiles/reviewer.yaml +13 -13
- package/dist/core/dispatcher.js +1 -1
- package/dist/core/entity-operations.js +29 -3
- package/dist/core/execution.js +1 -1
- package/dist/core/loops/verbs.js +0 -1
- package/dist/core/messaging.js +2 -2
- package/dist/core/protocol-skills.js +164 -164
- package/dist/core/runtime-signals.js +1 -1
- package/dist/core/search.js +19 -2
- package/dist/core/security-guard.js +207 -207
- package/dist/core/spawn-check.js +16 -2
- package/dist/core/staleness.js +1 -1
- package/dist/core/store-resolution.js +26 -7
- package/dist/core/worktree.js +18 -18
- package/dist/facts.js +3 -3
- package/dist/facts.json +2 -2
- package/docs/PROTOCOL.md +1 -1
- package/docs/adapters/openclaw.md +43 -43
- package/docs/architecture/project-refs.md +328 -328
- package/docs/cli.md +2093 -2093
- package/docs/concepts/coordination.md +52 -52
- package/docs/concepts/coordinator-runbook.md +129 -129
- package/docs/concepts/dispatch-lifecycle.md +245 -245
- package/docs/concepts/event-log-store.md +928 -928
- package/docs/concepts/ideation-loop.md +317 -317
- package/docs/concepts/loop-engine.md +520 -511
- package/docs/concepts/mcp-governance.md +268 -268
- package/docs/concepts/memory.md +84 -84
- package/docs/concepts/multi-agent-workflows.md +167 -167
- package/docs/concepts/observer-protocol.md +361 -361
- package/docs/concepts/plans-and-claims.md +217 -217
- package/docs/concepts/project-md-convention.md +35 -35
- package/docs/concepts/runtime-notes.md +38 -38
- package/docs/concepts/troubleshooting.md +254 -254
- package/docs/concepts/workspace-bootstrapping.md +142 -142
- package/docs/context-format-changelog.md +35 -35
- package/docs/context-format.md +48 -48
- package/docs/index.md +65 -65
- package/docs/integrations/agents.md +158 -158
- package/docs/integrations/claude-code.md +23 -23
- package/docs/integrations/cline.md +77 -77
- package/docs/integrations/continue.md +55 -55
- package/docs/integrations/copilot.md +68 -68
- package/docs/integrations/cursor.md +23 -23
- package/docs/integrations/kilocode.md +72 -72
- package/docs/integrations/mcp.md +377 -377
- package/docs/integrations/mistral-vibe.md +122 -122
- package/docs/integrations/openclaw.md +92 -92
- package/docs/integrations/opencode.md +84 -84
- package/docs/integrations/overview.md +115 -115
- package/docs/integrations/roo.md +71 -71
- package/docs/integrations/windsurf.md +77 -77
- package/docs/mcp-schema-changelog.md +360 -356
- package/docs/playbooks/integration/index.md +121 -121
- package/docs/playbooks/orchestration.md +37 -0
- package/docs/playbooks/productivity/index.md +99 -99
- package/docs/playbooks/team/index.md +117 -117
- package/docs/product/agent-first-model.md +184 -184
- package/docs/product/entity-model-audit.md +462 -462
- package/docs/product/positioning.md +86 -86
- package/docs/quickstart-existing-project.md +107 -107
- package/docs/quickstart.md +183 -183
- package/docs/release-maintenance.md +79 -79
- package/docs/reputation.md +52 -52
- package/docs/review.md +45 -45
- package/docs/security.md +212 -212
- package/docs/server-operations.md +118 -118
- package/docs/storage.md +106 -106
- package/package.json +80 -65
- package/docs/concepts/event-log-store-critique-A.md +0 -333
- package/docs/concepts/event-log-store-critique-B.md +0 -353
- package/docs/concepts/event-log-store-phase0-measurements.md +0 -58
- package/docs/concepts/event-log-store-proposal-A.md +0 -365
- package/docs/concepts/event-log-store-proposal-B.md +0 -404
- package/docs/concepts/identity-model-proposal.md +0 -371
package/dist/commands/mcp.js
CHANGED
|
@@ -39,7 +39,7 @@ import { createCapability, createTool as createRegistryTool } from '../core/regi
|
|
|
39
39
|
import { detectAiAgent } from '../core/ai-agent-detection.js';
|
|
40
40
|
import { checkGitPresence, scanGitRepos, parseRoots, parseRepoSelection, parseAgentSelection, getDetectedSetupAgentNames, getInstalledAgentNames, runGlobalInstall, initReposAndConfigureAgents, readSetupState, ALL_KNOWN_AGENTS, } from './setup.js';
|
|
41
41
|
import { buildAgentInventory } from '../core/agent-inventory.js';
|
|
42
|
-
import { resolveEffectiveCwd, resolveProjectRef, resolveTargetStore } from '../core/store-resolution.js';
|
|
42
|
+
import { resolveEffectiveCwd, resolveEffectiveCwdInfo, resolveProjectRef, resolveTargetStore } from '../core/store-resolution.js';
|
|
43
43
|
import { assessBootstrapNeed, probeForQuickSetup, buildQuickSetupProbeResponse, buildOnboardingPreview, resolveEmptyMemoryRecommendation } from '../core/setup-flow.js';
|
|
44
44
|
import { ensureUserStore, resolveHomeDir } from '../core/setup-state.js';
|
|
45
45
|
import { createPlan, addStep as addStepOp, completeStep as completeStepOp, updateStep as updateStepOp, deleteStep as deleteStepOp, deletePlan as deletePlanOp } from '../core/operations/plan.js';
|
|
@@ -167,6 +167,8 @@ export const MCP_READ_TOOLS = [
|
|
|
167
167
|
type: { type: 'string', description: 'Filter by section: decisions, constraints, traps, handoffs, candidates, plans, sequences.' },
|
|
168
168
|
section: { type: 'string', description: 'Filter by section (state, candidates, runtime).' },
|
|
169
169
|
since: { type: 'string', description: 'Filter items created after this ISO date.' },
|
|
170
|
+
project: { type: 'string', description: 'Optional project name/path to search. Defaults to the active project.' },
|
|
171
|
+
includeLegacy: { type: 'boolean', description: 'Include records with provenance.kind="legacy" (default false). Response reports excluded_legacy when false.' },
|
|
170
172
|
limit: { type: 'number', description: 'Maximum number of results to return (default 10).' },
|
|
171
173
|
offset: { type: 'number', description: 'Number of results to skip (for pagination).' },
|
|
172
174
|
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.' },
|
|
@@ -1782,6 +1784,32 @@ function explicitSessionIdFromEnv() {
|
|
|
1782
1784
|
|| process.env.CLAUDE_SESSION_ID?.trim()
|
|
1783
1785
|
|| process.env.COPILOT_SESSION_ID?.trim();
|
|
1784
1786
|
}
|
|
1787
|
+
function projectInfoForCwd(cwd) {
|
|
1788
|
+
try {
|
|
1789
|
+
const config = loadConfig(cwd);
|
|
1790
|
+
return { path: cwd, name: config.project_name };
|
|
1791
|
+
}
|
|
1792
|
+
catch {
|
|
1793
|
+
return { path: cwd };
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
function scopeMetadataForTarget(args, targetCwd, effectiveScope) {
|
|
1797
|
+
const hasExplicitProject = typeof args.project === 'string' && args.project.trim().length > 0;
|
|
1798
|
+
return {
|
|
1799
|
+
resolved_project: projectInfoForCwd(targetCwd),
|
|
1800
|
+
active_source: hasExplicitProject ? 'explicit' : effectiveScope.active_source,
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
function renderProvenanceFilterNote(result) {
|
|
1804
|
+
const parts = [];
|
|
1805
|
+
if ((result.excluded_legacy ?? 0) > 0) {
|
|
1806
|
+
parts.push(`${result.excluded_legacy} legacy item(s) excluded (pass filter.includeLegacy=true to include them)`);
|
|
1807
|
+
}
|
|
1808
|
+
if ((result.excluded_low_confidence_auto_reflect ?? 0) > 0) {
|
|
1809
|
+
parts.push(`${result.excluded_low_confidence_auto_reflect} low-confidence auto_reflect item(s) excluded (lower filter.minAutoReflectConfidence to include them)`);
|
|
1810
|
+
}
|
|
1811
|
+
return parts.length > 0 ? parts.join('; ') : undefined;
|
|
1812
|
+
}
|
|
1785
1813
|
export function parseMcpLine(line) {
|
|
1786
1814
|
let parsed;
|
|
1787
1815
|
try {
|
|
@@ -2557,6 +2585,11 @@ import { handleMcpReadToolCall } from './mcp-read-handlers.js';
|
|
|
2557
2585
|
export { handleMcpReadToolCall };
|
|
2558
2586
|
async function _executeMcpToolCallInner(payload) {
|
|
2559
2587
|
const { name, args, cwd, connectionSessionId } = payload;
|
|
2588
|
+
const scopeInfo = payload.effectiveScope ?? {
|
|
2589
|
+
cwd,
|
|
2590
|
+
active_source: 'cwd',
|
|
2591
|
+
resolved_project: projectInfoForCwd(cwd),
|
|
2592
|
+
};
|
|
2560
2593
|
try {
|
|
2561
2594
|
if (isLegacyMcpToolFacadeDisabled(name)) {
|
|
2562
2595
|
return { response: createLegacyMcpToolDisabledResponse() };
|
|
@@ -2568,7 +2601,7 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
2568
2601
|
}
|
|
2569
2602
|
if (MCP_READ_TOOLS.some((tool) => tool.name === name) || LEGACY_READ_TOOL_HANDLERS.has(name)) {
|
|
2570
2603
|
return {
|
|
2571
|
-
response: appendLegacyMcpToolWarning(toolResponse(handleMcpReadToolCall(name, args, { cwd })), name),
|
|
2604
|
+
response: appendLegacyMcpToolWarning(toolResponse(handleMcpReadToolCall(name, args, { cwd, connectionSessionId, effectiveScope: scopeInfo })), name),
|
|
2572
2605
|
};
|
|
2573
2606
|
}
|
|
2574
2607
|
// Resolve model once for all write operations
|
|
@@ -6214,6 +6247,7 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6214
6247
|
try {
|
|
6215
6248
|
const entity = String(args.entity ?? '');
|
|
6216
6249
|
const targetCwd = resolveProjectCwd(args.project, cwd);
|
|
6250
|
+
const targetScope = scopeMetadataForTarget(args, targetCwd, scopeInfo);
|
|
6217
6251
|
// pln#460 follow-up — some MCP clients (notably Claude Code with a
|
|
6218
6252
|
// tool schema that declares `filter: { type: 'object' }` without a
|
|
6219
6253
|
// sub-property schema) stringify the filter object before shipping
|
|
@@ -6269,10 +6303,10 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6269
6303
|
const bounded = boundListResult(result, offset, charBudget);
|
|
6270
6304
|
const warnings = collectLoadValidationWarnings(entity, targetCwd);
|
|
6271
6305
|
const nextActions = [
|
|
6272
|
-
{ tool: 'bclaw_get', args: { entity, id: '<id from items>' }, when: 'to read one item in full' },
|
|
6306
|
+
{ tool: 'bclaw_get', args: { entity, id: '<id from items>', ...(args.project ? { project: args.project } : {}), ...(args.budget_tokens ? { budget_tokens: args.budget_tokens } : {}) }, when: 'to read one item in full' },
|
|
6273
6307
|
];
|
|
6274
6308
|
if (bounded.has_more) {
|
|
6275
|
-
nextActions.push({ tool: 'bclaw_find', args: { entity, filter: { ...filter, offset: bounded.next_offset } }, when: 'to fetch the next page' });
|
|
6309
|
+
nextActions.push({ tool: 'bclaw_find', args: { entity, filter: { ...filter, offset: bounded.next_offset }, ...(args.project ? { project: args.project } : {}), ...(args.budget_tokens ? { budget_tokens: args.budget_tokens } : {}) }, when: 'to fetch the next page' });
|
|
6276
6310
|
}
|
|
6277
6311
|
// structuredContent is the canonical MCP return channel that clients
|
|
6278
6312
|
// (VS Code extension, Codex, etc.) read for machine-parseable data.
|
|
@@ -6281,10 +6315,20 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6281
6315
|
// `result.items` arrived as undefined on the client — the root cause
|
|
6282
6316
|
// of the VS Code Backlog section rendering empty.
|
|
6283
6317
|
const moreNote = bounded.has_more ? ` (returned ${bounded.returned}; ${result.total - bounded.returned} more — offset ${bounded.next_offset})` : '';
|
|
6318
|
+
const provenanceFilterNote = renderProvenanceFilterNote(result);
|
|
6319
|
+
const legacyNote = provenanceFilterNote
|
|
6320
|
+
? `; ${provenanceFilterNote}`
|
|
6321
|
+
: '';
|
|
6284
6322
|
return {
|
|
6285
6323
|
response: toolResponse({
|
|
6286
|
-
content: [{ type: 'text', text: `✔ ${result.total} ${entity} item(s)${moreNote}` }],
|
|
6287
|
-
structuredContent: {
|
|
6324
|
+
content: [{ type: 'text', text: `✔ ${result.total} ${entity} item(s)${moreNote}${legacyNote}` }],
|
|
6325
|
+
structuredContent: {
|
|
6326
|
+
...bounded,
|
|
6327
|
+
warnings,
|
|
6328
|
+
resolved_project: targetScope.resolved_project,
|
|
6329
|
+
active_source: targetScope.active_source,
|
|
6330
|
+
next_actions: nextActions,
|
|
6331
|
+
},
|
|
6288
6332
|
}),
|
|
6289
6333
|
};
|
|
6290
6334
|
}
|
|
@@ -6361,6 +6405,7 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6361
6405
|
}
|
|
6362
6406
|
const rawData = (args.data ?? {});
|
|
6363
6407
|
const targetCwd = resolveProjectCwd(args.project, cwd);
|
|
6408
|
+
const targetScope = scopeMetadataForTarget(args, targetCwd, scopeInfo);
|
|
6364
6409
|
// Auto-fill identity fields. Without this, a caller who omits author/agent
|
|
6365
6410
|
// creates a schema-invalid record that is silently dropped on read and
|
|
6366
6411
|
// GC'd from disk on the next mutation.
|
|
@@ -6392,7 +6437,11 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6392
6437
|
return {
|
|
6393
6438
|
response: toolResponse({
|
|
6394
6439
|
content: [{ type: 'text', text: `✔ created ${entity} ${result.id}` }],
|
|
6395
|
-
structuredContent: {
|
|
6440
|
+
structuredContent: {
|
|
6441
|
+
...result,
|
|
6442
|
+
resolved_project: targetScope.resolved_project,
|
|
6443
|
+
active_source: targetScope.active_source,
|
|
6444
|
+
},
|
|
6396
6445
|
}),
|
|
6397
6446
|
};
|
|
6398
6447
|
}
|
|
@@ -6406,13 +6455,18 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6406
6455
|
const id = String(args.id ?? '');
|
|
6407
6456
|
const patch = (args.patch ?? {});
|
|
6408
6457
|
const targetCwd = resolveProjectCwd(args.project, cwd);
|
|
6458
|
+
const targetScope = scopeMetadataForTarget(args, targetCwd, scopeInfo);
|
|
6409
6459
|
const { agent_name, agent_id } = resolveCanonicalAuthor(args, cwd, connectionSessionId);
|
|
6410
6460
|
const result = updateEntity(entity, id, patch, targetCwd);
|
|
6411
6461
|
appendAuditEntry({ actor: agent_name, ...(agent_id ? { actor_id: agent_id } : {}), action: 'update', item_id: id, item_type: entity }, targetCwd);
|
|
6412
6462
|
return {
|
|
6413
6463
|
response: toolResponse({
|
|
6414
6464
|
content: [{ type: 'text', text: `✔ updated ${entity} ${id}` }],
|
|
6415
|
-
structuredContent: {
|
|
6465
|
+
structuredContent: {
|
|
6466
|
+
...result,
|
|
6467
|
+
resolved_project: targetScope.resolved_project,
|
|
6468
|
+
active_source: targetScope.active_source,
|
|
6469
|
+
},
|
|
6416
6470
|
}),
|
|
6417
6471
|
};
|
|
6418
6472
|
}
|
|
@@ -6426,13 +6480,18 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6426
6480
|
const id = String(args.id ?? '');
|
|
6427
6481
|
const purge = args.purge === true;
|
|
6428
6482
|
const targetCwd = resolveProjectCwd(args.project, cwd);
|
|
6483
|
+
const targetScope = scopeMetadataForTarget(args, targetCwd, scopeInfo);
|
|
6429
6484
|
const { agent_name, agent_id } = resolveCanonicalAuthor(args, cwd, connectionSessionId);
|
|
6430
6485
|
const result = removeEntity(entity, id, targetCwd, purge);
|
|
6431
6486
|
appendAuditEntry({ actor: agent_name, ...(agent_id ? { actor_id: agent_id } : {}), action: 'delete', item_id: id, item_type: entity, reason: purge ? 'purged' : 'archived' }, targetCwd);
|
|
6432
6487
|
return {
|
|
6433
6488
|
response: toolResponse({
|
|
6434
6489
|
content: [{ type: 'text', text: `✔ removed ${entity} ${id}` }],
|
|
6435
|
-
structuredContent: {
|
|
6490
|
+
structuredContent: {
|
|
6491
|
+
...result,
|
|
6492
|
+
resolved_project: targetScope.resolved_project,
|
|
6493
|
+
active_source: targetScope.active_source,
|
|
6494
|
+
},
|
|
6436
6495
|
}),
|
|
6437
6496
|
};
|
|
6438
6497
|
}
|
|
@@ -6454,13 +6513,18 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6454
6513
|
const to = String(args.to ?? '');
|
|
6455
6514
|
const reason = args.reason;
|
|
6456
6515
|
const targetCwd = resolveProjectCwd(args.project, cwd);
|
|
6516
|
+
const targetScope = scopeMetadataForTarget(args, targetCwd, scopeInfo);
|
|
6457
6517
|
const { agent_name, agent_id } = resolveCanonicalAuthor(args, cwd, connectionSessionId);
|
|
6458
6518
|
const result = transitionEntity(entity, id, to, targetCwd, reason);
|
|
6459
6519
|
appendAuditEntry({ actor: agent_name, ...(agent_id ? { actor_id: agent_id } : {}), action: 'update', item_id: id, item_type: entity, reason: `transition ${result.from} → ${to}${reason ? ` (${reason})` : ''}` }, targetCwd);
|
|
6460
6520
|
return {
|
|
6461
6521
|
response: toolResponse({
|
|
6462
6522
|
content: [{ type: 'text', text: `✔ ${entity} ${id}: ${result.from} → ${to}` }],
|
|
6463
|
-
structuredContent: {
|
|
6523
|
+
structuredContent: {
|
|
6524
|
+
...result,
|
|
6525
|
+
resolved_project: targetScope.resolved_project,
|
|
6526
|
+
active_source: targetScope.active_source,
|
|
6527
|
+
},
|
|
6464
6528
|
}),
|
|
6465
6529
|
};
|
|
6466
6530
|
}
|
|
@@ -6504,9 +6568,10 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
6504
6568
|
*/
|
|
6505
6569
|
export async function executeMcpToolCall(payload) {
|
|
6506
6570
|
const baseCwd = payload.cwd;
|
|
6507
|
-
const
|
|
6508
|
-
? baseCwd
|
|
6509
|
-
:
|
|
6571
|
+
const effective = payload.name === 'bclaw_switch'
|
|
6572
|
+
? { cwd: baseCwd, active_source: 'cwd', resolved_project: undefined }
|
|
6573
|
+
: resolveEffectiveCwdInfo({ baseCwd, sessionId: payload.connectionSessionId });
|
|
6574
|
+
const cwd = effective.cwd;
|
|
6510
6575
|
const envClaimId = process.env.BRAINCLAW_CLAIM_ID?.trim() || undefined;
|
|
6511
6576
|
// ── Auto-session ────────────────────────────────────────────────────────────
|
|
6512
6577
|
let autoSessionId;
|
|
@@ -6564,6 +6629,7 @@ export async function executeMcpToolCall(payload) {
|
|
|
6564
6629
|
...payload,
|
|
6565
6630
|
cwd,
|
|
6566
6631
|
connectionSessionId: effectiveConnectionSessionId,
|
|
6632
|
+
effectiveScope: effective,
|
|
6567
6633
|
});
|
|
6568
6634
|
// Apply legacy deprecation warning uniformly (Phase 3 slice 3g). Read tools
|
|
6569
6635
|
// already get it at line 2560; write tools historically did not. This
|
package/dist/commands/switch.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { loadActiveProject, saveActiveProject, clearActiveProject } from '../core/active-project.js';
|
|
3
|
-
import { buildOperationalIdentity, loadCurrentSession, saveCurrentSession } from '../core/identity.js';
|
|
3
|
+
import { buildOperationalIdentity, loadCurrentSession, loadSessionById, saveCurrentSession } from '../core/identity.js';
|
|
4
4
|
import { memoryExists } from '../core/io.js';
|
|
5
5
|
import { resolveProjectRef } from '../core/store-resolution.js';
|
|
6
6
|
import { resolveCrossProjectLinks, resolveProjectCwd } from '../core/cross-project.js';
|
|
@@ -44,10 +44,28 @@ export function switchProject(projectRef, options = {}) {
|
|
|
44
44
|
catch { /* name is optional */ }
|
|
45
45
|
const now = new Date().toISOString();
|
|
46
46
|
const sessionOnly = options.sessionOnly ?? true;
|
|
47
|
-
let session = loadCurrentSession(cwd);
|
|
47
|
+
let session = options.sessionId ? loadSessionById(options.sessionId, cwd) : loadCurrentSession(cwd);
|
|
48
48
|
if (!session && sessionOnly) {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
if (options.sessionId) {
|
|
50
|
+
const identity = buildOperationalIdentity(undefined, cwd, {
|
|
51
|
+
sessionId: options.sessionId,
|
|
52
|
+
persistImplicitSession: false,
|
|
53
|
+
});
|
|
54
|
+
saveCurrentSession({
|
|
55
|
+
session_id: options.sessionId,
|
|
56
|
+
started_at: now,
|
|
57
|
+
last_seen_at: now,
|
|
58
|
+
agent: identity.agent,
|
|
59
|
+
agent_id: identity.agent_id,
|
|
60
|
+
host_id: identity.host_id,
|
|
61
|
+
user: process.env.USER || process.env.USERNAME || undefined,
|
|
62
|
+
pid: process.pid,
|
|
63
|
+
}, cwd);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
buildOperationalIdentity(undefined, cwd, { persistImplicitSession: true });
|
|
67
|
+
}
|
|
68
|
+
session = options.sessionId ? loadSessionById(options.sessionId, cwd) : loadCurrentSession(cwd);
|
|
51
69
|
}
|
|
52
70
|
if (session && sessionOnly) {
|
|
53
71
|
saveCurrentSession({
|
|
@@ -78,11 +96,14 @@ export function switchProject(projectRef, options = {}) {
|
|
|
78
96
|
* List available projects in the workspace.
|
|
79
97
|
*/
|
|
80
98
|
export function listAvailableProjects(cwd) {
|
|
99
|
+
return listAvailableProjectsForSession(cwd);
|
|
100
|
+
}
|
|
101
|
+
export function listAvailableProjectsForSession(cwd, sessionId) {
|
|
81
102
|
const wsRoot = findOutermostWorkspaceRoot(cwd ?? process.cwd());
|
|
82
103
|
if (!wsRoot) {
|
|
83
104
|
throw new Error('No brainclaw workspace found.');
|
|
84
105
|
}
|
|
85
|
-
const sessionActive = loadCurrentSession(cwd)?.active_project;
|
|
106
|
+
const sessionActive = (sessionId ? loadSessionById(sessionId, cwd) : loadCurrentSession(cwd))?.active_project;
|
|
86
107
|
const globalActive = loadActiveProject(wsRoot);
|
|
87
108
|
const active = sessionActive ?? globalActive;
|
|
88
109
|
const activeSource = sessionActive ? 'session' : globalActive ? 'global' : 'none';
|
package/dist/commands/version.js
CHANGED
|
@@ -8,7 +8,7 @@ import { generateAgentReleaseNotes } from './release-notes.js';
|
|
|
8
8
|
export function runVersion(options = {}) {
|
|
9
9
|
const cwd = options.cwd ?? process.cwd();
|
|
10
10
|
const initialized = memoryExists(cwd);
|
|
11
|
-
|
|
11
|
+
const config = initialized ? loadConfig(cwd) : undefined;
|
|
12
12
|
let publishedLocalRelease;
|
|
13
13
|
if (options.publishLocal) {
|
|
14
14
|
if (!initialized || !config) {
|
|
@@ -23,9 +23,21 @@ const AGENT_ALIASES = {
|
|
|
23
23
|
'vibe': 'mistral-vibe',
|
|
24
24
|
'hermes-agent': 'hermes',
|
|
25
25
|
};
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Resolve an alias to its canonical agent name (case-insensitive).
|
|
28
|
+
*
|
|
29
|
+
* Agent names are case-insensitive: every canonical profile key and every alias
|
|
30
|
+
* is lowercase, so we trim + lowercase the input before resolving. This is the
|
|
31
|
+
* single normalization point — registry, messaging, spawn-check and the
|
|
32
|
+
* coordinate/dispatch pre-flight all route through here, so a target like
|
|
33
|
+
* "Codex" or "Gemini" resolves identically to "codex" / "gemini". Without it the
|
|
34
|
+
* dispatch pre-flight collapsed an unresolved name into "no CLI spawn template
|
|
35
|
+
* (IDE-only?)" and silently dropped the reviewer (github-copilot/Gemini hit this
|
|
36
|
+
* passing targetAgents=["Codex"]).
|
|
37
|
+
*/
|
|
27
38
|
export function resolveAgentAlias(name) {
|
|
28
|
-
|
|
39
|
+
const key = name.trim().toLowerCase();
|
|
40
|
+
return AGENT_ALIASES[key] ?? key;
|
|
29
41
|
}
|
|
30
42
|
const PROFILES = {
|
|
31
43
|
// --- Code agents (interactive, IDE-driven) ---
|
|
@@ -314,7 +326,10 @@ const _customProfiles = new Map();
|
|
|
314
326
|
* Custom profiles take precedence over DEFAULT_CAPABILITY_PROFILES on lookup.
|
|
315
327
|
*/
|
|
316
328
|
export function registerCapabilityProfile(profile) {
|
|
317
|
-
|
|
329
|
+
// Key by the normalized (lowercased) name so lookups through the
|
|
330
|
+
// case-insensitive resolveAgentAlias match regardless of the casing the
|
|
331
|
+
// registrant used.
|
|
332
|
+
_customProfiles.set(profile.name.trim().toLowerCase(), profile);
|
|
318
333
|
}
|
|
319
334
|
/**
|
|
320
335
|
* Get the capability profile for an agent by name.
|
|
@@ -667,7 +682,7 @@ export function resolveBriefMode(agentName) {
|
|
|
667
682
|
* pln#528 — capability matrix DERIVED from the spawn template, so it stays in
|
|
668
683
|
* sync with how each agent is actually invoked (no per-profile duplication).
|
|
669
684
|
*
|
|
670
|
-
* The motivating reality (debrief
|
|
685
|
+
* The motivating reality (a cross-project field debrief): codex is spawned with
|
|
671
686
|
* `--sandbox workspace-write`, which (a) does NOT wire the brainclaw MCP server
|
|
672
687
|
* and (b) puts `.git` outside the sandbox root — so a sandboxed worker can
|
|
673
688
|
* neither call `bclaw_*` nor `git commit`, regardless of the profile's nominal
|
package/dist/core/agent-files.js
CHANGED
|
@@ -13,46 +13,46 @@ export { resetMcpCommandCache };
|
|
|
13
13
|
export const BRAINCLAW_SECTION_START = '<!-- brainclaw:start -->';
|
|
14
14
|
export const BRAINCLAW_SECTION_END = '<!-- brainclaw:end -->';
|
|
15
15
|
export function buildBrainclawSection(storageDir) {
|
|
16
|
-
return `${BRAINCLAW_SECTION_START}
|
|
17
|
-
## Brainclaw — shared project memory
|
|
18
|
-
|
|
19
|
-
This project uses brainclaw for shared coordination between humans and agents.
|
|
20
|
-
|
|
21
|
-
### Session start (required)
|
|
22
|
-
|
|
23
|
-
1. Run \`brainclaw context\` to load shared state (constraints, decisions, traps, plans, handoffs)
|
|
24
|
-
2. Check **Your open work** for active claims and in-progress plans assigned to you
|
|
25
|
-
3. Respect active claims from other agents — check \`brainclaw claim list\` before editing a claimed scope
|
|
26
|
-
|
|
27
|
-
### Before finishing (required)
|
|
28
|
-
|
|
29
|
-
1. Release claims you opened: \`brainclaw claim release <id>\` — or \`brainclaw session-end --auto-release\`
|
|
30
|
-
2. Update completed plan items: \`brainclaw plan update <id> --status done\`
|
|
31
|
-
|
|
32
|
-
### Recording work
|
|
33
|
-
|
|
34
|
-
\`\`\`bash
|
|
35
|
-
brainclaw memory create decision "<text>" # record a decision
|
|
36
|
-
brainclaw memory create constraint "<text>" # record an active constraint
|
|
37
|
-
brainclaw memory create trap "<text>" # record a known trap
|
|
38
|
-
brainclaw claim create "<text>" --scope <path> # claim a scope before editing
|
|
39
|
-
brainclaw plan create "<text>" # add a shared work item
|
|
40
|
-
\`\`\`
|
|
41
|
-
|
|
42
|
-
Memory is stored in \`${storageDir}/\`. Run \`brainclaw doctor\` to verify health.
|
|
16
|
+
return `${BRAINCLAW_SECTION_START}
|
|
17
|
+
## Brainclaw — shared project memory
|
|
18
|
+
|
|
19
|
+
This project uses brainclaw for shared coordination between humans and agents.
|
|
20
|
+
|
|
21
|
+
### Session start (required)
|
|
22
|
+
|
|
23
|
+
1. Run \`brainclaw context\` to load shared state (constraints, decisions, traps, plans, handoffs)
|
|
24
|
+
2. Check **Your open work** for active claims and in-progress plans assigned to you
|
|
25
|
+
3. Respect active claims from other agents — check \`brainclaw claim list\` before editing a claimed scope
|
|
26
|
+
|
|
27
|
+
### Before finishing (required)
|
|
28
|
+
|
|
29
|
+
1. Release claims you opened: \`brainclaw claim release <id>\` — or \`brainclaw session-end --auto-release\`
|
|
30
|
+
2. Update completed plan items: \`brainclaw plan update <id> --status done\`
|
|
31
|
+
|
|
32
|
+
### Recording work
|
|
33
|
+
|
|
34
|
+
\`\`\`bash
|
|
35
|
+
brainclaw memory create decision "<text>" # record a decision
|
|
36
|
+
brainclaw memory create constraint "<text>" # record an active constraint
|
|
37
|
+
brainclaw memory create trap "<text>" # record a known trap
|
|
38
|
+
brainclaw claim create "<text>" --scope <path> # claim a scope before editing
|
|
39
|
+
brainclaw plan create "<text>" # add a shared work item
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
Memory is stored in \`${storageDir}/\`. Run \`brainclaw doctor\` to verify health.
|
|
43
43
|
${BRAINCLAW_SECTION_END}`;
|
|
44
44
|
}
|
|
45
45
|
export function buildHygieneSection() {
|
|
46
|
-
return `## Brainclaw — required coordination
|
|
47
|
-
|
|
48
|
-
Before starting work:
|
|
49
|
-
1. Run \`brainclaw context\` (or \`brainclaw context --json\`) to load shared memory
|
|
50
|
-
2. Run \`brainclaw claim list\` — do not edit a file claimed by another agent
|
|
51
|
-
3. Create a plan for significant work: \`brainclaw plan create "<description>"\`
|
|
52
|
-
4. Claim files you will modify: \`brainclaw claim create "<description>" --scope <path>\`
|
|
53
|
-
|
|
54
|
-
Before finishing:
|
|
55
|
-
1. Run \`brainclaw session-end --auto-release\` — releases claims and updates plans
|
|
46
|
+
return `## Brainclaw — required coordination
|
|
47
|
+
|
|
48
|
+
Before starting work:
|
|
49
|
+
1. Run \`brainclaw context\` (or \`brainclaw context --json\`) to load shared memory
|
|
50
|
+
2. Run \`brainclaw claim list\` — do not edit a file claimed by another agent
|
|
51
|
+
3. Create a plan for significant work: \`brainclaw plan create "<description>"\`
|
|
52
|
+
4. Claim files you will modify: \`brainclaw claim create "<description>" --scope <path>\`
|
|
53
|
+
|
|
54
|
+
Before finishing:
|
|
55
|
+
1. Run \`brainclaw session-end --auto-release\` — releases claims and updates plans
|
|
56
56
|
2. Or manually: \`brainclaw claim release <id>\` and \`brainclaw plan update <id> --status done\``;
|
|
57
57
|
}
|
|
58
58
|
export function hasBrainclawSection(content) {
|
|
@@ -727,13 +727,13 @@ export function describeAutoConfigWrite(result) {
|
|
|
727
727
|
return `✔ ${verb} ${result.label} at ${displayPath}`;
|
|
728
728
|
}
|
|
729
729
|
export function buildClaudeCodeCommandText() {
|
|
730
|
-
return `Load brainclaw project memory and prepare for coordinated work.
|
|
731
|
-
|
|
732
|
-
Steps:
|
|
733
|
-
1. Run \`brainclaw context --json\` — load constraints, decisions, traps, plans, handoffs
|
|
734
|
-
2. Run \`brainclaw claim list\` — check what files other agents have claimed
|
|
735
|
-
3. Before editing any file, run \`brainclaw claim create "<description>" --scope <path>\`
|
|
736
|
-
4. Before finishing, run \`brainclaw session-end --auto-release\`
|
|
730
|
+
return `Load brainclaw project memory and prepare for coordinated work.
|
|
731
|
+
|
|
732
|
+
Steps:
|
|
733
|
+
1. Run \`brainclaw context --json\` — load constraints, decisions, traps, plans, handoffs
|
|
734
|
+
2. Run \`brainclaw claim list\` — check what files other agents have claimed
|
|
735
|
+
3. Before editing any file, run \`brainclaw claim create "<description>" --scope <path>\`
|
|
736
|
+
4. Before finishing, run \`brainclaw session-end --auto-release\`
|
|
737
737
|
`;
|
|
738
738
|
}
|
|
739
739
|
export function ensureClineMcpConfig(cwd) {
|
|
@@ -799,34 +799,34 @@ export function ensureWindsurfMcpConfig(homeDir) {
|
|
|
799
799
|
*/
|
|
800
800
|
export function ensureWindsurfModernRules(cwd) {
|
|
801
801
|
const filePath = path.join(cwd, WINDSURF_MODERN_RULES_RELATIVE_PATH);
|
|
802
|
-
const content = `# Brainclaw coordination rules
|
|
803
|
-
|
|
804
|
-
Brainclaw is the shared coordination layer. Use its MCP facades first — the CLI is only a fallback when MCP is unavailable.
|
|
805
|
-
|
|
806
|
-
## Session start
|
|
807
|
-
|
|
808
|
-
Call \`bclaw_work(intent)\`. It loads memory (constraints, decisions, traps, plans, handoffs), resolves the claim, and starts a session in a single call.
|
|
809
|
-
|
|
810
|
-
- \`bclaw_work(intent: "resume")\` — continue existing work (auto-surfaces the context diff).
|
|
811
|
-
- \`bclaw_work(intent: "execute", scope: "<path>", task: "<text>")\` — start new work and claim the scope.
|
|
812
|
-
- \`bclaw_work(intent: "consult")\` — read-only context without claiming.
|
|
813
|
-
|
|
814
|
-
## During work
|
|
815
|
-
|
|
816
|
-
- Mark plan steps done: \`bclaw_complete_step(planId, stepId)\`.
|
|
817
|
-
- Read the inbox: \`bclaw_read_inbox\`.
|
|
818
|
-
- Record notes, decisions, traps: \`bclaw_write_note\`, \`bclaw_create(entity, data)\`.
|
|
819
|
-
|
|
820
|
-
## To coordinate with other agents
|
|
821
|
-
|
|
822
|
-
\`bclaw_coordinate(intent)\` — \`assign\`, \`consult\`, \`review\`, or \`reroute\`.
|
|
823
|
-
|
|
824
|
-
## Before finishing
|
|
825
|
-
|
|
826
|
-
- Release your claims: \`bclaw_release_claim(id)\`.
|
|
827
|
-
- Close the session: \`bclaw_session_end\` (auto-releases remaining claims).
|
|
828
|
-
|
|
829
|
-
CLI fallback only when MCP is unavailable: \`brainclaw context\` / \`brainclaw session-end --auto-release\`.
|
|
802
|
+
const content = `# Brainclaw coordination rules
|
|
803
|
+
|
|
804
|
+
Brainclaw is the shared coordination layer. Use its MCP facades first — the CLI is only a fallback when MCP is unavailable.
|
|
805
|
+
|
|
806
|
+
## Session start
|
|
807
|
+
|
|
808
|
+
Call \`bclaw_work(intent)\`. It loads memory (constraints, decisions, traps, plans, handoffs), resolves the claim, and starts a session in a single call.
|
|
809
|
+
|
|
810
|
+
- \`bclaw_work(intent: "resume")\` — continue existing work (auto-surfaces the context diff).
|
|
811
|
+
- \`bclaw_work(intent: "execute", scope: "<path>", task: "<text>")\` — start new work and claim the scope.
|
|
812
|
+
- \`bclaw_work(intent: "consult")\` — read-only context without claiming.
|
|
813
|
+
|
|
814
|
+
## During work
|
|
815
|
+
|
|
816
|
+
- Mark plan steps done: \`bclaw_complete_step(planId, stepId)\`.
|
|
817
|
+
- Read the inbox: \`bclaw_read_inbox\`.
|
|
818
|
+
- Record notes, decisions, traps: \`bclaw_write_note\`, \`bclaw_create(entity, data)\`.
|
|
819
|
+
|
|
820
|
+
## To coordinate with other agents
|
|
821
|
+
|
|
822
|
+
\`bclaw_coordinate(intent)\` — \`assign\`, \`consult\`, \`review\`, or \`reroute\`.
|
|
823
|
+
|
|
824
|
+
## Before finishing
|
|
825
|
+
|
|
826
|
+
- Release your claims: \`bclaw_release_claim(id)\`.
|
|
827
|
+
- Close the session: \`bclaw_session_end\` (auto-releases remaining claims).
|
|
828
|
+
|
|
829
|
+
CLI fallback only when MCP is unavailable: \`brainclaw context\` / \`brainclaw session-end --auto-release\`.
|
|
830
830
|
`;
|
|
831
831
|
const { created, updated } = writeTextFileIfChanged(filePath, content);
|
|
832
832
|
return {
|
|
@@ -840,22 +840,22 @@ CLI fallback only when MCP is unavailable: \`brainclaw context\` / \`brainclaw s
|
|
|
840
840
|
}
|
|
841
841
|
export function ensureCopilotSkill(cwd) {
|
|
842
842
|
const filePath = path.join(cwd, '.github', 'skills', 'brainclaw-context', 'SKILL.md');
|
|
843
|
-
const content = `---
|
|
844
|
-
name: brainclaw-context
|
|
845
|
-
description: "Use this skill when you need the latest Brainclaw context, active plans, constraints, traps, or handoffs before coding. Trigger phrases: refresh project memory, load brainclaw context, inspect active plans, inspect constraints."
|
|
846
|
-
---
|
|
847
|
-
|
|
848
|
-
# Brainclaw Context
|
|
849
|
-
|
|
850
|
-
Fetch live project memory before significant edits. Prefer the Brainclaw MCP facade; use the CLI only as a fallback when MCP is unavailable.
|
|
851
|
-
|
|
852
|
-
## Steps
|
|
853
|
-
|
|
854
|
-
1. Call \`bclaw_work(intent: "resume")\` to continue existing work, or \`bclaw_work(intent: "consult")\` for read-only context. The response contains active plans, constraints, decisions, traps, and handoffs.
|
|
855
|
-
2. Prefer Brainclaw state over stale assumptions from older instructions or prior sessions.
|
|
856
|
-
3. Coordinate with other agents via \`bclaw_coordinate(intent)\` (\`assign\`, \`consult\`, \`review\`).
|
|
857
|
-
|
|
858
|
-
CLI fallback: \`brainclaw context --json\` if the MCP server is not reachable.
|
|
843
|
+
const content = `---
|
|
844
|
+
name: brainclaw-context
|
|
845
|
+
description: "Use this skill when you need the latest Brainclaw context, active plans, constraints, traps, or handoffs before coding. Trigger phrases: refresh project memory, load brainclaw context, inspect active plans, inspect constraints."
|
|
846
|
+
---
|
|
847
|
+
|
|
848
|
+
# Brainclaw Context
|
|
849
|
+
|
|
850
|
+
Fetch live project memory before significant edits. Prefer the Brainclaw MCP facade; use the CLI only as a fallback when MCP is unavailable.
|
|
851
|
+
|
|
852
|
+
## Steps
|
|
853
|
+
|
|
854
|
+
1. Call \`bclaw_work(intent: "resume")\` to continue existing work, or \`bclaw_work(intent: "consult")\` for read-only context. The response contains active plans, constraints, decisions, traps, and handoffs.
|
|
855
|
+
2. Prefer Brainclaw state over stale assumptions from older instructions or prior sessions.
|
|
856
|
+
3. Coordinate with other agents via \`bclaw_coordinate(intent)\` (\`assign\`, \`consult\`, \`review\`).
|
|
857
|
+
|
|
858
|
+
CLI fallback: \`brainclaw context --json\` if the MCP server is not reachable.
|
|
859
859
|
`;
|
|
860
860
|
const { created, updated } = writeTextFileIfChanged(filePath, content);
|
|
861
861
|
return {
|
|
@@ -877,24 +877,24 @@ CLI fallback: \`brainclaw context --json\` if the MCP server is not reachable.
|
|
|
877
877
|
*/
|
|
878
878
|
export function ensureUniversalBrainclawSkill(cwd) {
|
|
879
879
|
const filePath = path.join(cwd, UNIVERSAL_SKILL_RELATIVE_PATH);
|
|
880
|
-
const content = `---
|
|
881
|
-
name: brainclaw
|
|
882
|
-
description: 'Load and act on Brainclaw project memory, active claims, plans, traps, and handoffs before code changes. Trigger: refresh brainclaw context, check active claims, load coordination state.'
|
|
883
|
-
allowed-tools: 'Read Bash(npx brainclaw:*)'
|
|
884
|
-
---
|
|
885
|
-
|
|
886
|
-
# Brainclaw
|
|
887
|
-
|
|
888
|
-
Load the shared coordination state before any significant code change. Prefer the Brainclaw MCP facade; the CLI is a fallback when MCP is not reachable.
|
|
889
|
-
|
|
890
|
-
## Steps
|
|
891
|
-
|
|
892
|
-
1. Call \`bclaw_work(intent)\` — \`resume\` to continue existing work, \`execute\` to claim a new scope, or \`consult\` for read-only context. The response gives you memory, active claims, plans, traps, and handoffs.
|
|
893
|
-
2. Respect active claims from other agents reported in the response; do not edit a claimed scope unless you own the claim.
|
|
894
|
-
3. Use \`bclaw_coordinate(intent)\` to assign, consult, or review other agents when needed.
|
|
895
|
-
4. When done, call \`bclaw_session_end\` (auto-releases your remaining claims).
|
|
896
|
-
|
|
897
|
-
CLI fallback only: \`brainclaw context --json\` / \`brainclaw claim create\` / \`brainclaw session-end --auto-release\` if the MCP server is unavailable.
|
|
880
|
+
const content = `---
|
|
881
|
+
name: brainclaw
|
|
882
|
+
description: 'Load and act on Brainclaw project memory, active claims, plans, traps, and handoffs before code changes. Trigger: refresh brainclaw context, check active claims, load coordination state.'
|
|
883
|
+
allowed-tools: 'Read Bash(npx brainclaw:*)'
|
|
884
|
+
---
|
|
885
|
+
|
|
886
|
+
# Brainclaw
|
|
887
|
+
|
|
888
|
+
Load the shared coordination state before any significant code change. Prefer the Brainclaw MCP facade; the CLI is a fallback when MCP is not reachable.
|
|
889
|
+
|
|
890
|
+
## Steps
|
|
891
|
+
|
|
892
|
+
1. Call \`bclaw_work(intent)\` — \`resume\` to continue existing work, \`execute\` to claim a new scope, or \`consult\` for read-only context. The response gives you memory, active claims, plans, traps, and handoffs.
|
|
893
|
+
2. Respect active claims from other agents reported in the response; do not edit a claimed scope unless you own the claim.
|
|
894
|
+
3. Use \`bclaw_coordinate(intent)\` to assign, consult, or review other agents when needed.
|
|
895
|
+
4. When done, call \`bclaw_session_end\` (auto-releases your remaining claims).
|
|
896
|
+
|
|
897
|
+
CLI fallback only: \`brainclaw context --json\` / \`brainclaw claim create\` / \`brainclaw session-end --auto-release\` if the MCP server is unavailable.
|
|
898
898
|
`;
|
|
899
899
|
const { created, updated } = writeTextFileIfChanged(filePath, content);
|
|
900
900
|
return {
|
|
@@ -1005,19 +1005,19 @@ export function ensureVscodeExtensionRecommendation(cwd) {
|
|
|
1005
1005
|
}
|
|
1006
1006
|
export function ensureCursorMdc(cwd) {
|
|
1007
1007
|
const filePath = path.join(cwd, '.cursor', 'rules', 'brainclaw-mcp-shim.mdc');
|
|
1008
|
-
const content = `---
|
|
1009
|
-
description: Use this rule when work depends on live Brainclaw memory or active project rules.
|
|
1010
|
-
globs: "**/*"
|
|
1011
|
-
alwaysApply: true
|
|
1012
|
-
---
|
|
1013
|
-
|
|
1014
|
-
Brainclaw is the shared coordination layer. Call the MCP facade first; the CLI is only a fallback when MCP is not reachable.
|
|
1015
|
-
|
|
1016
|
-
Before significant edits or when asked about project rules, call \`bclaw_work(intent: "consult")\` (or \`"resume"\` if continuing a task) via the Brainclaw MCP server. The response carries active claims, in-progress plans, constraints, decisions, traps, and handoffs.
|
|
1017
|
-
|
|
1018
|
-
If the response lists active claims or in-progress plans, follow them before editing. Use \`bclaw_coordinate(intent)\` to dispatch, consult, or review other agents.
|
|
1019
|
-
|
|
1020
|
-
CLI fallback only when MCP is unavailable: \`brainclaw context --json\`.
|
|
1008
|
+
const content = `---
|
|
1009
|
+
description: Use this rule when work depends on live Brainclaw memory or active project rules.
|
|
1010
|
+
globs: "**/*"
|
|
1011
|
+
alwaysApply: true
|
|
1012
|
+
---
|
|
1013
|
+
|
|
1014
|
+
Brainclaw is the shared coordination layer. Call the MCP facade first; the CLI is only a fallback when MCP is not reachable.
|
|
1015
|
+
|
|
1016
|
+
Before significant edits or when asked about project rules, call \`bclaw_work(intent: "consult")\` (or \`"resume"\` if continuing a task) via the Brainclaw MCP server. The response carries active claims, in-progress plans, constraints, decisions, traps, and handoffs.
|
|
1017
|
+
|
|
1018
|
+
If the response lists active claims or in-progress plans, follow them before editing. Use \`bclaw_coordinate(intent)\` to dispatch, consult, or review other agents.
|
|
1019
|
+
|
|
1020
|
+
CLI fallback only when MCP is unavailable: \`brainclaw context --json\`.
|
|
1021
1021
|
`;
|
|
1022
1022
|
const { created, updated } = writeTextFileIfChanged(filePath, content);
|
|
1023
1023
|
return {
|