brainclaw 0.28.0 → 1.5.3
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 +193 -170
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli.js +683 -23
- package/dist/commands/accept.js +3 -0
- package/dist/commands/add-step.js +11 -26
- package/dist/commands/agent-board.js +70 -3
- package/dist/commands/audit.js +19 -0
- package/dist/commands/check-policy.js +54 -0
- package/dist/commands/check-security-mcp.js +145 -0
- package/dist/commands/check-security.js +106 -0
- package/dist/commands/claim-resource.js +1 -0
- package/dist/commands/codev.js +672 -0
- package/dist/commands/compact.js +74 -0
- package/dist/commands/complete-step.js +16 -26
- package/dist/commands/constraint.js +8 -20
- package/dist/commands/decision.js +9 -20
- package/dist/commands/delete-plan.js +10 -12
- package/dist/commands/delete-step.js +16 -0
- package/dist/commands/dispatch.js +163 -0
- package/dist/commands/doctor.js +1122 -49
- package/dist/commands/enable-agent.js +1 -0
- package/dist/commands/export.js +280 -22
- package/dist/commands/handoff.js +33 -0
- package/dist/commands/harvest.js +189 -0
- package/dist/commands/hooks.js +82 -25
- package/dist/commands/inbox.js +169 -0
- package/dist/commands/init.js +38 -31
- package/dist/commands/install-hooks.js +71 -44
- package/dist/commands/link.js +89 -0
- package/dist/commands/list-claims.js +48 -3
- package/dist/commands/list-plans.js +129 -25
- package/dist/commands/loops-handlers.js +409 -0
- package/dist/commands/mcp-read-handlers.js +1628 -0
- package/dist/commands/mcp-schemas.generated.js +74 -0
- package/dist/commands/mcp.js +4244 -1475
- package/dist/commands/plan-resource.js +64 -0
- package/dist/commands/plan.js +12 -26
- package/dist/commands/prune.js +37 -2
- package/dist/commands/reflect.js +20 -7
- package/dist/commands/release-claim.js +11 -6
- package/dist/commands/release-notes.js +170 -0
- package/dist/commands/repair.js +210 -0
- package/dist/commands/run-profile.js +57 -0
- package/dist/commands/sequence.js +113 -0
- package/dist/commands/session-end.js +423 -14
- package/dist/commands/session-start.js +214 -41
- package/dist/commands/setup-security.js +103 -0
- package/dist/commands/setup.js +42 -4
- package/dist/commands/stale.js +109 -0
- package/dist/commands/switch.js +131 -10
- package/dist/commands/trap.js +14 -31
- package/dist/commands/update-handoff.js +63 -4
- package/dist/commands/update-plan.js +21 -28
- package/dist/commands/update-step.js +37 -0
- package/dist/commands/upgrade.js +313 -6
- package/dist/commands/usage.js +102 -0
- package/dist/commands/version.js +20 -0
- package/dist/commands/who.js +124 -0
- package/dist/commands/worktree.js +105 -0
- package/dist/core/actions.js +315 -0
- package/dist/core/agent-capability.js +610 -17
- package/dist/core/agent-context.js +7 -1
- package/dist/core/agent-files.js +1169 -85
- package/dist/core/agent-integrations.js +160 -5
- package/dist/core/agent-inventory.js +2 -0
- package/dist/core/agent-profiles.js +93 -0
- package/dist/core/agent-registry.js +162 -30
- package/dist/core/agentrun-reconciler.js +345 -0
- package/dist/core/agentruns.js +424 -0
- package/dist/core/ai-agent-detection.js +31 -10
- package/dist/core/archival.js +77 -0
- package/dist/core/assignment-sweeper.js +82 -0
- package/dist/core/assignments.js +367 -0
- package/dist/core/audit.js +30 -0
- package/dist/core/bootstrap.js +61 -10
- package/dist/core/brainclaw-version.js +94 -2
- package/dist/core/candidates.js +93 -2
- package/dist/core/claims.js +419 -0
- package/dist/core/codev-metrics.js +77 -0
- package/dist/core/codev-personas.js +31 -0
- package/dist/core/codev-plan-gen.js +35 -0
- package/dist/core/codev-prompts.js +74 -0
- package/dist/core/codev-responses.js +62 -0
- package/dist/core/codev-rounds.js +218 -0
- package/dist/core/config.js +4 -0
- package/dist/core/context.js +454 -34
- package/dist/core/coordination.js +201 -6
- package/dist/core/cross-project.js +230 -16
- package/dist/core/default-profiles/doctor.yaml +11 -0
- package/dist/core/default-profiles/janitor.yaml +11 -0
- package/dist/core/default-profiles/onboarder.yaml +11 -0
- package/dist/core/default-profiles/reviewer.yaml +13 -0
- package/dist/core/dispatcher.js +1189 -0
- package/dist/core/duplicates.js +2 -2
- package/dist/core/entity-operations.js +450 -0
- package/dist/core/entity-registry.js +344 -0
- package/dist/core/event-log.js +1 -0
- package/dist/core/events.js +106 -2
- package/dist/core/execution-adapters.js +154 -0
- package/dist/core/execution-context.js +63 -0
- package/dist/core/execution-profile.js +270 -0
- package/dist/core/execution.js +255 -0
- package/dist/core/facade-schema.js +81 -0
- package/dist/core/federation-cloud.js +99 -0
- package/dist/core/federation-message.js +52 -0
- package/dist/core/federation-transport.js +65 -0
- package/dist/core/gc-semantic.js +482 -0
- package/dist/core/governance.js +247 -0
- package/dist/core/guards.js +19 -0
- package/dist/core/ideation.js +72 -0
- package/dist/core/identity.js +252 -28
- package/dist/core/ids.js +6 -0
- package/dist/core/input-validation.js +2 -2
- package/dist/core/instruction-templates.js +344 -136
- package/dist/core/io.js +90 -11
- package/dist/core/lock.js +6 -2
- package/dist/core/loops/brief-assembly.js +213 -0
- package/dist/core/loops/facade-schema.js +148 -0
- package/dist/core/loops/index.js +7 -0
- package/dist/core/loops/iteration-engine.js +139 -0
- package/dist/core/loops/lock.js +385 -0
- package/dist/core/loops/store.js +201 -0
- package/dist/core/loops/types.js +403 -0
- package/dist/core/loops/verbs.js +534 -0
- package/dist/core/markdown.js +15 -3
- package/dist/core/memory-compactor.js +432 -0
- package/dist/core/memory-git.js +152 -8
- package/dist/core/messaging.js +278 -0
- package/dist/core/migration.js +32 -1
- package/dist/core/mutation-pipeline.js +4 -2
- package/dist/core/operations/memory-mutation.js +129 -0
- package/dist/core/operations/memory-write.js +78 -0
- package/dist/core/operations/plan.js +190 -0
- package/dist/core/policy.js +169 -0
- package/dist/core/repo-analysis.js +67 -0
- package/dist/core/reputation.js +9 -3
- package/dist/core/schema.js +546 -21
- package/dist/core/search.js +21 -2
- package/dist/core/security-cache.js +71 -0
- package/dist/core/security-guard.js +152 -0
- package/dist/core/security-scoring.js +86 -0
- package/dist/core/sequence.js +130 -0
- package/dist/core/socket-client.js +113 -0
- package/dist/core/staleness.js +246 -0
- package/dist/core/state.js +98 -22
- package/dist/core/store-resolution.js +54 -12
- package/dist/core/toml-writer.js +76 -0
- package/dist/core/upgrades/backup.js +232 -0
- package/dist/core/upgrades/health-check.js +169 -0
- package/dist/core/upgrades/patches/candidate-archive.js +145 -0
- package/dist/core/upgrades/patches/handoff-review-strip.js +128 -0
- package/dist/core/upgrades/patches/provenance-rollout.js +136 -0
- package/dist/core/upgrades/schema-version.js +97 -0
- package/dist/core/worktree.js +606 -0
- package/dist/facts.js +114 -0
- package/dist/facts.json +111 -0
- package/docs/architecture/project-refs.md +5 -1
- package/docs/cli.md +690 -43
- package/docs/concepts/ideation-loop.md +317 -0
- package/docs/concepts/loop-engine.md +456 -0
- package/docs/concepts/mcp-governance.md +268 -0
- package/docs/concepts/memory-staleness.md +122 -0
- package/docs/concepts/multi-agent-workflows.md +166 -0
- package/docs/concepts/plans-and-claims.md +31 -6
- package/docs/concepts/project-md-convention.md +35 -0
- package/docs/concepts/troubleshooting.md +220 -0
- package/docs/concepts/upgrade-cli.md +202 -0
- package/docs/concepts/upgrade-dogfood-procedure.md +114 -0
- package/docs/context-format-changelog.md +2 -2
- package/docs/context-format.md +2 -2
- package/docs/index.md +68 -0
- package/docs/integrations/agents.md +15 -16
- package/docs/integrations/cline.md +88 -0
- package/docs/integrations/codex.md +75 -23
- package/docs/integrations/continue.md +60 -0
- package/docs/integrations/copilot.md +67 -9
- package/docs/integrations/kilocode.md +72 -0
- package/docs/integrations/mcp.md +304 -21
- package/docs/integrations/mistral-vibe.md +122 -0
- package/docs/integrations/opencode.md +84 -0
- package/docs/integrations/overview.md +23 -8
- package/docs/integrations/roo.md +74 -0
- package/docs/integrations/windsurf.md +83 -0
- package/docs/mcp-schema-changelog.md +191 -1
- package/docs/playbooks/integration/index.md +121 -0
- package/docs/playbooks/productivity/index.md +102 -0
- package/docs/playbooks/team/index.md +122 -0
- package/docs/product/agent-first-model.md +184 -0
- package/docs/product/entity-model-audit.md +462 -0
- package/docs/quickstart-existing-project.md +135 -0
- package/docs/quickstart.md +124 -37
- package/docs/release-maintenance.md +79 -0
- package/docs/review.md +2 -0
- package/docs/server-operations.md +118 -0
- package/package.json +20 -12
- package/dist/commands/claude-desktop-extension.js +0 -18
- package/dist/commands/diff.js +0 -99
- package/dist/core/claude-desktop-extension.js +0 -224
package/dist/core/ids.js
CHANGED
|
@@ -10,8 +10,14 @@ const PREFIXES = {
|
|
|
10
10
|
open_handoffs: 'hnd',
|
|
11
11
|
plan_items: 'pln',
|
|
12
12
|
plan_steps: 'stp',
|
|
13
|
+
sequences: 'seq',
|
|
13
14
|
instruction_entries: 'ins',
|
|
14
15
|
ai_surface_tasks: 'ast',
|
|
16
|
+
inbox_messages: 'msg',
|
|
17
|
+
assignments: 'asgn',
|
|
18
|
+
runs: 'run',
|
|
19
|
+
actions: 'act',
|
|
20
|
+
runtime_events: 'evt',
|
|
15
21
|
};
|
|
16
22
|
const ID_COUNTER_FILE = '.id-counter.json';
|
|
17
23
|
function counterPath(cwd) {
|
|
@@ -11,7 +11,7 @@ export const TtlSchema = z
|
|
|
11
11
|
.string()
|
|
12
12
|
.regex(TTL_PATTERN, 'Invalid TTL format. Use <number><unit> where unit is m (minutes), h (hours), or d (days). Example: 30m, 2h, 7d');
|
|
13
13
|
function formatZodError(error, field) {
|
|
14
|
-
return error.
|
|
14
|
+
return error.issues.map((e) => ({ field, message: e.message }));
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Validate CLI mutation inputs. On failure: prints error and calls process.exit(1).
|
|
@@ -41,7 +41,7 @@ export function validateCliInput(text, tags) {
|
|
|
41
41
|
export function validateCliTtl(ttl) {
|
|
42
42
|
const result = TtlSchema.safeParse(ttl);
|
|
43
43
|
if (!result.success) {
|
|
44
|
-
console.error(`Error: ${result.error.
|
|
44
|
+
console.error(`Error: ${result.error.issues[0]?.message ?? 'Invalid TTL'}`);
|
|
45
45
|
process.exit(1);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -2,220 +2,358 @@
|
|
|
2
2
|
* Adaptive instruction file templates — generates brainclaw section content
|
|
3
3
|
* based on the agent's capability profile (tier A/B/C).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Two surface types:
|
|
6
|
+
* STABLE (versioned, rare refresh) — vision, protocol, durable constraints, instructions
|
|
7
|
+
* LIVE (gitignored, frequent refresh) — plans, claims, traps, decisions, sequences
|
|
8
8
|
*
|
|
9
|
-
* Tier
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Tier delivery:
|
|
10
|
+
* Tier A (MCP + hooks): stable file only — live context via hooks/MCP
|
|
11
|
+
* Tier B (MCP, no hooks): stable file + live companion file
|
|
12
|
+
* Tier C (no MCP): stable file + live companion file (richer, only source)
|
|
12
13
|
*/
|
|
13
14
|
/**
|
|
14
|
-
* Render the brainclaw section content for an instruction file
|
|
15
|
-
*
|
|
15
|
+
* Render the STABLE brainclaw section content for an instruction file.
|
|
16
|
+
* This is the versioned file that changes rarely (on upgrade, convention change).
|
|
17
|
+
*
|
|
18
|
+
* For backward compatibility, this is also the entry point used by existing
|
|
19
|
+
* export code. Tier B/C stable output no longer includes traps/plans/decisions.
|
|
16
20
|
*/
|
|
17
21
|
export function renderBrainclawSection(input) {
|
|
22
|
+
return renderStableSection(input);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Render stable content only: vision, protocol, constraints, instructions.
|
|
26
|
+
* No traps, plans, decisions, claims — those go in the live companion.
|
|
27
|
+
*/
|
|
28
|
+
export function renderStableSection(input) {
|
|
18
29
|
const { profile } = input;
|
|
19
30
|
switch (profile.templateTier) {
|
|
20
|
-
case 'A': return
|
|
21
|
-
case 'B': return
|
|
22
|
-
case 'C': return
|
|
31
|
+
case 'A': return renderStableTierA(input);
|
|
32
|
+
case 'B': return renderStableTierB(input);
|
|
33
|
+
case 'C': return renderStableTierC(input);
|
|
23
34
|
}
|
|
24
35
|
}
|
|
25
|
-
|
|
26
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Render LIVE companion content: traps, plans, claims, candidates, handoffs,
|
|
38
|
+
* and (for tier C) recent decisions.
|
|
39
|
+
* This is the gitignored file refreshed on plan/claim/sequence mutations.
|
|
40
|
+
*
|
|
41
|
+
* Returns undefined when the profile does not emit a filesystem live
|
|
42
|
+
* companion.
|
|
43
|
+
*/
|
|
44
|
+
export function renderLiveSection(input) {
|
|
45
|
+
const tier = resolveLiveCompanionTier(input.profile);
|
|
46
|
+
if (!tier)
|
|
47
|
+
return undefined;
|
|
48
|
+
return renderLiveCompanion(input, {
|
|
49
|
+
tier,
|
|
50
|
+
maxTraps: tier === 'C' ? input.maxTraps ?? 10 : input.maxTraps ?? 5,
|
|
51
|
+
maxPlans: tier === 'C' ? input.maxPlans ?? 10 : input.maxPlans ?? 5,
|
|
52
|
+
maxHandoffs: tier === 'C' ? 10 : 5,
|
|
53
|
+
includeDecisions: tier === 'C',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// ─── Tier A: Stable only ────────────────────────────────────────────────────
|
|
57
|
+
// Minimal: vision + protocol. Everything else arrives via hooks/MCP.
|
|
58
|
+
function renderStableTierA(input) {
|
|
27
59
|
const sections = [];
|
|
28
60
|
const included = [];
|
|
29
61
|
sections.push(renderHeader(input));
|
|
30
62
|
included.push('header');
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
sections.push(renderEstimationRule());
|
|
36
|
-
included.push('estimation');
|
|
37
|
-
sections.push(renderVersionCheckRule());
|
|
38
|
-
included.push('version-check');
|
|
39
|
-
const constraints = renderConstraints(input.state);
|
|
40
|
-
if (constraints) {
|
|
41
|
-
sections.push(constraints);
|
|
42
|
-
included.push('constraints');
|
|
63
|
+
const vision = renderVisionSection(input);
|
|
64
|
+
if (vision) {
|
|
65
|
+
sections.push(vision);
|
|
66
|
+
included.push('vision');
|
|
43
67
|
}
|
|
68
|
+
sections.push(renderSessionProtocol());
|
|
69
|
+
included.push('protocol');
|
|
70
|
+
sections.push(renderUserWorkflow());
|
|
71
|
+
included.push('user-workflow');
|
|
72
|
+
sections.push(renderAutonomyContract());
|
|
73
|
+
included.push('autonomy-contract');
|
|
74
|
+
sections.push(renderAvailableTools());
|
|
75
|
+
included.push('available-tools');
|
|
44
76
|
const instructions = renderInstructions(input.resolvedInstructions);
|
|
45
77
|
if (instructions) {
|
|
46
78
|
sections.push(instructions);
|
|
47
79
|
included.push('instructions');
|
|
48
80
|
}
|
|
49
|
-
return {
|
|
50
|
-
content: sections.join('\n\n'),
|
|
51
|
-
tier: 'A',
|
|
52
|
-
sectionsIncluded: included,
|
|
53
|
-
};
|
|
81
|
+
return { content: sections.join('\n\n'), tier: 'A', sectionsIncluded: included };
|
|
54
82
|
}
|
|
55
|
-
// ─── Tier B:
|
|
56
|
-
function
|
|
83
|
+
// ─── Tier B: Stable + Live ──────────────────────────────────────────────────
|
|
84
|
+
function renderStableTierB(input) {
|
|
57
85
|
const sections = [];
|
|
58
86
|
const included = [];
|
|
59
87
|
sections.push(renderHeader(input));
|
|
60
88
|
included.push('header');
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
const vision = renderVisionSection(input);
|
|
90
|
+
if (vision) {
|
|
91
|
+
sections.push(vision);
|
|
92
|
+
included.push('vision');
|
|
93
|
+
}
|
|
94
|
+
sections.push(renderSessionProtocol());
|
|
64
95
|
included.push('protocol');
|
|
65
|
-
sections.push(
|
|
66
|
-
included.push('
|
|
67
|
-
sections.push(
|
|
68
|
-
included.push('
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
71
|
-
sections.push(
|
|
72
|
-
included.push('
|
|
96
|
+
sections.push(renderUserWorkflow());
|
|
97
|
+
included.push('user-workflow');
|
|
98
|
+
sections.push(renderAutonomyContract());
|
|
99
|
+
included.push('autonomy-contract');
|
|
100
|
+
const rules = renderWorkingRules(input.state);
|
|
101
|
+
if (rules) {
|
|
102
|
+
sections.push(rules);
|
|
103
|
+
included.push('working-rules');
|
|
104
|
+
}
|
|
105
|
+
const arch = renderArchitecture(input.state);
|
|
106
|
+
if (arch) {
|
|
107
|
+
sections.push(arch);
|
|
108
|
+
included.push('architecture');
|
|
73
109
|
}
|
|
74
110
|
const instructions = renderInstructions(input.resolvedInstructions);
|
|
75
111
|
if (instructions) {
|
|
76
112
|
sections.push(instructions);
|
|
77
113
|
included.push('instructions');
|
|
78
114
|
}
|
|
79
|
-
|
|
80
|
-
|
|
115
|
+
return { content: sections.join('\n\n'), tier: 'B', sectionsIncluded: included };
|
|
116
|
+
}
|
|
117
|
+
const LIVE_COMPANION_TIER_B_AGENTS = new Set([
|
|
118
|
+
'cursor',
|
|
119
|
+
'cline',
|
|
120
|
+
'windsurf',
|
|
121
|
+
'github-copilot',
|
|
122
|
+
]);
|
|
123
|
+
function resolveLiveCompanionTier(profile) {
|
|
124
|
+
if (profile.templateTier === 'C')
|
|
125
|
+
return 'C';
|
|
126
|
+
if (profile.templateTier === 'B')
|
|
127
|
+
return 'B';
|
|
128
|
+
return LIVE_COMPANION_TIER_B_AGENTS.has(profile.name) ? 'B' : undefined;
|
|
129
|
+
}
|
|
130
|
+
function renderLiveCompanion(input, options) {
|
|
131
|
+
const sections = [];
|
|
132
|
+
const included = [];
|
|
133
|
+
sections.push(renderLiveHeader(input));
|
|
134
|
+
included.push('live-header');
|
|
135
|
+
const traps = renderTopTraps(input.state, options.maxTraps);
|
|
81
136
|
if (traps) {
|
|
82
137
|
sections.push(traps);
|
|
83
138
|
included.push('traps');
|
|
84
139
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
140
|
+
const plans = renderActivePlans(input.state, options.maxPlans);
|
|
141
|
+
if (plans) {
|
|
142
|
+
sections.push(plans);
|
|
143
|
+
included.push('plans');
|
|
144
|
+
}
|
|
145
|
+
const claims = renderActiveClaimsFromInput(input);
|
|
146
|
+
if (claims) {
|
|
147
|
+
sections.push(claims);
|
|
148
|
+
included.push('claims');
|
|
149
|
+
}
|
|
150
|
+
const candidates = renderPendingCandidates(input);
|
|
151
|
+
if (candidates) {
|
|
152
|
+
sections.push(candidates);
|
|
153
|
+
included.push('candidates');
|
|
154
|
+
}
|
|
155
|
+
const handoffs = renderOpenHandoffs(input.state, options.maxHandoffs);
|
|
156
|
+
if (handoffs) {
|
|
157
|
+
sections.push(handoffs);
|
|
158
|
+
included.push('handoffs');
|
|
159
|
+
}
|
|
160
|
+
if (options.includeDecisions) {
|
|
161
|
+
const decisions = renderRecentDecisions(input.state);
|
|
162
|
+
if (decisions) {
|
|
163
|
+
sections.push(decisions);
|
|
164
|
+
included.push('decisions');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { content: sections.join('\n\n'), tier: options.tier, sectionsIncluded: included };
|
|
90
168
|
}
|
|
91
|
-
// ─── Tier C:
|
|
92
|
-
function
|
|
169
|
+
// ─── Tier C: Stable + Live (richer) ─────────────────────────────────────────
|
|
170
|
+
function renderStableTierC(input) {
|
|
93
171
|
const sections = [];
|
|
94
172
|
const included = [];
|
|
95
173
|
sections.push(renderHeader(input));
|
|
96
174
|
included.push('header');
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
175
|
+
const vision = renderVisionSection(input);
|
|
176
|
+
if (vision) {
|
|
177
|
+
sections.push(vision);
|
|
178
|
+
included.push('vision');
|
|
179
|
+
}
|
|
180
|
+
sections.push(renderSessionProtocol());
|
|
100
181
|
included.push('protocol');
|
|
101
|
-
sections.push(
|
|
102
|
-
included.push('
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
182
|
+
sections.push(renderUserWorkflow());
|
|
183
|
+
included.push('user-workflow');
|
|
184
|
+
sections.push(renderAutonomyContract());
|
|
185
|
+
included.push('autonomy-contract');
|
|
186
|
+
const rules = renderWorkingRules(input.state);
|
|
187
|
+
if (rules) {
|
|
188
|
+
sections.push(rules);
|
|
189
|
+
included.push('working-rules');
|
|
190
|
+
}
|
|
191
|
+
const arch = renderArchitecture(input.state);
|
|
192
|
+
if (arch) {
|
|
193
|
+
sections.push(arch);
|
|
194
|
+
included.push('architecture');
|
|
107
195
|
}
|
|
108
196
|
const instructions = renderInstructions(input.resolvedInstructions);
|
|
109
197
|
if (instructions) {
|
|
110
198
|
sections.push(instructions);
|
|
111
199
|
included.push('instructions');
|
|
112
200
|
}
|
|
113
|
-
|
|
114
|
-
const traps = renderTopTraps(input.state, input.maxTraps ?? 10);
|
|
115
|
-
if (traps) {
|
|
116
|
-
sections.push(traps);
|
|
117
|
-
included.push('traps');
|
|
118
|
-
}
|
|
119
|
-
const plans = renderActivePlans(input.state, input.maxPlans ?? 10);
|
|
120
|
-
if (plans) {
|
|
121
|
-
sections.push(plans);
|
|
122
|
-
included.push('plans');
|
|
123
|
-
}
|
|
124
|
-
const decisions = renderRecentDecisions(input.state);
|
|
125
|
-
if (decisions) {
|
|
126
|
-
sections.push(decisions);
|
|
127
|
-
included.push('decisions');
|
|
128
|
-
}
|
|
129
|
-
return {
|
|
130
|
-
content: sections.join('\n\n'),
|
|
131
|
-
tier: 'C',
|
|
132
|
-
sectionsIncluded: included,
|
|
133
|
-
};
|
|
201
|
+
return { content: sections.join('\n\n'), tier: 'C', sectionsIncluded: included };
|
|
134
202
|
}
|
|
135
203
|
// ─── Shared section renderers ────────────────────────────────────────────────
|
|
204
|
+
function renderVisionSection(input) {
|
|
205
|
+
if (!input.projectVision?.trim())
|
|
206
|
+
return undefined;
|
|
207
|
+
return [
|
|
208
|
+
`## brainclaw — this project`,
|
|
209
|
+
'',
|
|
210
|
+
input.projectVision.trim(),
|
|
211
|
+
].join('\n');
|
|
212
|
+
}
|
|
136
213
|
function renderHeader(input) {
|
|
137
214
|
return [
|
|
138
215
|
`> Managed by brainclaw v${input.brainclawVersion} — do not edit manually.`,
|
|
139
216
|
`> Regenerate: brainclaw export --format ${formatForAgent(input.profile.name)} --write`,
|
|
140
217
|
].join('\n');
|
|
141
218
|
}
|
|
142
|
-
function
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
];
|
|
148
|
-
if (profile.hasMcp) {
|
|
149
|
-
lines.push('Other agents and developers work in this repo. Without brainclaw context:', '- You may edit files another agent is actively working on', '- You will miss known traps and architectural decisions', '- You will duplicate or contradict planned work');
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
lines.push('Project context is maintained in brainclaw memory. This includes:', '- Active constraints that must be respected', '- Known traps to avoid repeating mistakes', '- Plans and decisions for ongoing work coordination');
|
|
153
|
-
}
|
|
154
|
-
return lines.join('\n');
|
|
219
|
+
function renderLiveHeader(_input) {
|
|
220
|
+
return [
|
|
221
|
+
`> Brainclaw live state — auto-refreshed, do not edit.`,
|
|
222
|
+
`> Last updated: ${new Date().toISOString().slice(0, 19)}`,
|
|
223
|
+
].join('\n');
|
|
155
224
|
}
|
|
156
|
-
function
|
|
225
|
+
function renderSessionProtocol() {
|
|
157
226
|
return [
|
|
158
227
|
'## brainclaw — session protocol',
|
|
159
228
|
'',
|
|
160
|
-
'
|
|
229
|
+
'1. Call `bclaw_work(intent)` to start working — it handles session, context, and claims automatically. Returns a compact payload by default; pass `compact: false` for the full context result, or use `bclaw_context(kind="memory")` after.',
|
|
230
|
+
'2. Use the canonical grammar (`bclaw_find` / `bclaw_get` / `bclaw_create` / `bclaw_update` / `bclaw_remove` / `bclaw_transition`) to work with memory objects (plans, decisions, constraints, traps, handoffs, claims, candidates, runtime_notes, …). Read `## brainclaw — working with memory` below for the full map.',
|
|
231
|
+
'3. Do not assume project state without reading brainclaw context first.',
|
|
161
232
|
'',
|
|
162
|
-
'
|
|
163
|
-
'
|
|
164
|
-
'
|
|
165
|
-
'
|
|
233
|
+
'_Escalation path (only when you orchestrate other agents) — by goal:_',
|
|
234
|
+
'- Start a code review / consult an agent / assign a scope → `bclaw_coordinate(intent=review|consult|assign)`',
|
|
235
|
+
'- Parallelize execute across a sequence\'s lanes → `bclaw_dispatch(intent=execute)`',
|
|
236
|
+
'- Drive a turn in a loop already assigned to you → `bclaw_loop(intent=turn|complete_turn|advance|close)`',
|
|
237
|
+
'',
|
|
238
|
+
'Do NOT call `bclaw_loop(intent=open)` directly — it creates a loop structure without dispatch, so the reviewer/participant never gets the work. Use the goal entries above.',
|
|
166
239
|
].join('\n');
|
|
167
240
|
}
|
|
168
|
-
function
|
|
241
|
+
function renderUserWorkflow() {
|
|
169
242
|
return [
|
|
170
|
-
'## brainclaw —
|
|
243
|
+
'## brainclaw — user workflow',
|
|
171
244
|
'',
|
|
172
|
-
'
|
|
245
|
+
'The intended end-to-end flow, executable by a single agent:',
|
|
173
246
|
'',
|
|
174
|
-
'
|
|
175
|
-
'2. Call `bclaw_get_context(target: "<file or dir>")` — load relevant memory',
|
|
176
|
-
'3. Call `bclaw_get_execution_context` — check for brainclaw updates',
|
|
177
|
-
'4. Check that no other agent has claimed your target scope',
|
|
178
|
-
'5. Call `bclaw_claim(scope)` before editing',
|
|
179
|
-
'6. Call `bclaw_write_note(text)` to record observations',
|
|
180
|
-
'7. Call `bclaw_session_end(auto_release: true)` when done',
|
|
181
|
-
].join('\n');
|
|
182
|
-
}
|
|
183
|
-
function renderProtocolTierC(profile) {
|
|
184
|
-
const lines = [
|
|
185
|
-
'## brainclaw — project coordination',
|
|
247
|
+
' ideation → plan (+ steps) → claim → implement → release claim → review → close step/plan → merge',
|
|
186
248
|
'',
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
249
|
+
'Multi-agent coordination is optional — use the escalation path only when delegating to another agent.',
|
|
250
|
+
'`sequence` is optional: add it between plan and claim when you want parallelized lanes across agents.',
|
|
251
|
+
'',
|
|
252
|
+
'**Entity → role in the flow:**',
|
|
253
|
+
'- `plan` — intended outcome. Create with `bclaw_create(plan, …)`, decompose with `bclaw_add_step`.',
|
|
254
|
+
'- `step` — incremental unit inside a plan; mark done with `bclaw_complete_step` as you implement.',
|
|
255
|
+
'- `sequence` — ordered lanes when work can be parallelized across claims/agents (optional).',
|
|
256
|
+
'- `claim` — advisory reservation of a scope before editing; release once implementation is ready for review.',
|
|
257
|
+
'- `handoff` — immutable snapshot of what moved to the next stage (review, merge).',
|
|
258
|
+
'- `candidate` — proposed decision / constraint / trap awaiting review before entering durable memory.',
|
|
259
|
+
'- `decision` / `constraint` / `trap` / `runtime_note` — captured along the way to preserve context for future sessions.',
|
|
260
|
+
'',
|
|
261
|
+
'**Review & Fix Loop (multi-turn delegation):**',
|
|
262
|
+
'- Start: `bclaw_coordinate(intent=review, open_loop=true, review_mode=symmetric|asymmetric, targetAgents=[reviewer])` — opens the loop AND dispatches the first turn to the reviewer.',
|
|
263
|
+
'- Drive: `bclaw_loop(intent=turn|complete_turn|advance|close)` for turns assigned to your slot.',
|
|
264
|
+
'- Anti-pattern: `bclaw_loop(intent=open)` alone — creates the loop structure without any dispatch, so nothing actually runs.',
|
|
265
|
+
'',
|
|
266
|
+
'Ideation / Debug / Research / Planning loops — *planned*. See `docs/product/agent-first-model.md` §3.',
|
|
267
|
+
].join('\n');
|
|
193
268
|
}
|
|
194
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Autonomy contract — emitted into every agent surface (pln#496 Phase 1).
|
|
271
|
+
*
|
|
272
|
+
* The contract binds protocol-defined transitions as MUST-execute, so live
|
|
273
|
+
* agents stop pausing on `should I send this reply? / merge? / release?`
|
|
274
|
+
* after every step. Without this, brainclaw collapses into a messaging layer
|
|
275
|
+
* with the human as the synchronization carrier-pigeon.
|
|
276
|
+
*
|
|
277
|
+
* Empirical motivation: in May 2026, multi-agent review threads systematically
|
|
278
|
+
* stalled at protocol-defined transitions (pln#480 worker did not release the
|
|
279
|
+
* claim, copilot pln#490 reviewer asked the human whether to send the reply).
|
|
280
|
+
* See feedback_agent_autonomy_gap + run_77e65e77 for the full diagnostic.
|
|
281
|
+
*
|
|
282
|
+
* Surface-fingerprint test (tests/unit/instruction-templates-autonomy-fingerprint.test.ts)
|
|
283
|
+
* fails CI if any tier drops this block — drift here re-introduces the gap.
|
|
284
|
+
*/
|
|
285
|
+
function renderAutonomyContract() {
|
|
195
286
|
return [
|
|
196
|
-
'## brainclaw —
|
|
287
|
+
'## brainclaw — autonomous workflow contract',
|
|
288
|
+
'',
|
|
289
|
+
'When a brainclaw protocol prescribes the next action after the one you just',
|
|
290
|
+
'completed, **execute it. Do not ask for permission.** brainclaw\'s coordination',
|
|
291
|
+
'promise depends on this — every avoidable pause forces the human back into the',
|
|
292
|
+
'synchronization loop, which is exactly what brainclaw is built to eliminate.',
|
|
293
|
+
'',
|
|
294
|
+
'**Protocol-defined transitions you MUST execute autonomously:**',
|
|
295
|
+
'',
|
|
296
|
+
'- IF you completed a review (assigned via `bclaw_coordinate(intent=review)` or',
|
|
297
|
+
' inbox `review_request` message) → produce findings → **send the reply with',
|
|
298
|
+
' your verdict via `bclaw_send_message(type="reply", thread_id=…)`**. Do not',
|
|
299
|
+
' ask whether to send.',
|
|
300
|
+
'- IF you receive a reply with an `LGTM` verdict AND you are the requester →',
|
|
301
|
+
' **close the loop and merge the branch yourself** (when you own the merge).',
|
|
302
|
+
' Do not pass the merge to the human.',
|
|
303
|
+
'- IF the reviewer reply contains findings → **apply the symmetric fixes you',
|
|
304
|
+
' can make**, commit on the same branch, then reroute via',
|
|
305
|
+
' `bclaw_send_message(type="reply", …)` for re-review. Do not stop after the',
|
|
306
|
+
' fixes.',
|
|
307
|
+
'- IF you have an active claim and your work is complete → call',
|
|
308
|
+
' `bclaw_release_claim(id=…, planStatus="done")`. Do not leave the claim',
|
|
309
|
+
' active for someone else to clean up.',
|
|
310
|
+
'- IF you have an `assignment_id` (you were dispatched via `bclaw_coordinate` /',
|
|
311
|
+
' `bclaw_dispatch`) → at end of work, call',
|
|
312
|
+
' `bclaw_assignment_update(assignment_id=…, status="completed", artifacts=[…])`.',
|
|
313
|
+
' The coordinator depends on this lifecycle event; without it, the loop never',
|
|
314
|
+
' converges and the supervisor cannot tell success from silent failure.',
|
|
315
|
+
'',
|
|
316
|
+
'**Legitimate reasons to pause and ask the human:**',
|
|
317
|
+
'',
|
|
318
|
+
'1. The action would be **destructive AND irreversible AND outside the',
|
|
319
|
+
' protocol** (e.g. `git push --force` on a public branch, dropping a',
|
|
320
|
+
' production database, deleting a non-empty memory cluster). Protocol-',
|
|
321
|
+
' defined merges to a local branch are NOT in this category.',
|
|
322
|
+
'2. The protocol genuinely **does not specify** the next action (e.g. a',
|
|
323
|
+
' verdict that splits the dispatched work into two new plans — needs',
|
|
324
|
+
' scoping judgement only the human owns).',
|
|
325
|
+
'3. The user has **explicitly told you to confirm** before specific actions',
|
|
326
|
+
' in this session.',
|
|
197
327
|
'',
|
|
198
|
-
'
|
|
199
|
-
'
|
|
328
|
+
'Asking *"should I send the reply?"* on a protocol-defined send is a UX bug,',
|
|
329
|
+
'not safety. If the next step appears in the workflow above — do it. The',
|
|
330
|
+
'empirical cost of skipping the contract: in May 2026, multi-agent review',
|
|
331
|
+
'threads systematically stalled at "should I send this reply?" / "should I',
|
|
332
|
+
'merge?", forcing the human supervisor to manually carry context between',
|
|
333
|
+
'agents. Stop reproducing that pattern.',
|
|
200
334
|
].join('\n');
|
|
201
335
|
}
|
|
202
|
-
|
|
336
|
+
// ─── Constraint sections (split by category) ────────────────────────────────
|
|
337
|
+
const RULE_CATEGORIES = new Set(['process', 'reliability', 'compatibility', 'security', 'other']);
|
|
338
|
+
const ARCH_CATEGORIES = new Set(['architecture', 'performance']);
|
|
339
|
+
function renderWorkingRules(state) {
|
|
340
|
+
const rules = state.active_constraints.filter((c) => c.status === 'active' && (!c.category || RULE_CATEGORIES.has(c.category)));
|
|
341
|
+
if (rules.length === 0)
|
|
342
|
+
return undefined;
|
|
203
343
|
return [
|
|
204
|
-
'## brainclaw —
|
|
344
|
+
'## brainclaw — working rules',
|
|
205
345
|
'',
|
|
206
|
-
|
|
207
|
-
'If a newer version is available, inform the developer and suggest updating.',
|
|
208
|
-
'Brainclaw updates may include new features, bug fixes, and improved coordination.',
|
|
346
|
+
...rules.map((c) => `- ${c.text}`),
|
|
209
347
|
].join('\n');
|
|
210
348
|
}
|
|
211
|
-
function
|
|
212
|
-
const
|
|
213
|
-
if (
|
|
349
|
+
function renderArchitecture(state) {
|
|
350
|
+
const arch = state.active_constraints.filter((c) => c.status === 'active' && c.category && ARCH_CATEGORIES.has(c.category));
|
|
351
|
+
if (arch.length === 0)
|
|
214
352
|
return undefined;
|
|
215
353
|
return [
|
|
216
|
-
'## brainclaw —
|
|
354
|
+
'## brainclaw — architecture',
|
|
217
355
|
'',
|
|
218
|
-
...
|
|
356
|
+
...arch.map((c) => `- ${c.text}`),
|
|
219
357
|
].join('\n');
|
|
220
358
|
}
|
|
221
359
|
function renderInstructions(instructions) {
|
|
@@ -227,6 +365,39 @@ function renderInstructions(instructions) {
|
|
|
227
365
|
...instructions.map((text) => `- ${text}`),
|
|
228
366
|
].join('\n');
|
|
229
367
|
}
|
|
368
|
+
function renderAvailableTools() {
|
|
369
|
+
return [
|
|
370
|
+
'## brainclaw — available tools',
|
|
371
|
+
'',
|
|
372
|
+
'The default MCP catalog is intentionally small. Start with `bclaw_work`, then use the canonical grammar for reads/writes on any entity. Coordination facades below are an **escalation path** for agents that orchestrate other agents — not the default loop.',
|
|
373
|
+
'',
|
|
374
|
+
'**Entry facades:** `bclaw_work(intent, compact?)`, `bclaw_context(kind)` — bclaw_work defaults to compact:true (minimal payload); use compact:false or bclaw_context for full memory',
|
|
375
|
+
'**Canonical grammar (standard tier) — your main tool for working with memory:**',
|
|
376
|
+
'- `bclaw_find(entity, filter?)` — list by type',
|
|
377
|
+
'- `bclaw_get(entity, id)` — read one',
|
|
378
|
+
'- `bclaw_create(entity, data)` — add a new plan / decision / constraint / trap / handoff / candidate / runtime_note',
|
|
379
|
+
'- `bclaw_update(entity, id, patch)` — edit in place',
|
|
380
|
+
'- `bclaw_remove(entity, id, purge?)` — soft-delete (or purge)',
|
|
381
|
+
'- `bclaw_transition(entity, id, to)` — change status (e.g. plan todo→in_progress→done)',
|
|
382
|
+
'',
|
|
383
|
+
'Entities supported by the grammar: plan, decision, constraint, trap, handoff, runtime_note, candidate, claim, action, assignment, agent_run.',
|
|
384
|
+
'',
|
|
385
|
+
'**Cross-project access (pln#359):** every canonical-grammar call, `bclaw_context`, and `bclaw_coordinate` accept an optional `project: <name>` argument that routes the operation to a linked project (cross_project_links from `brainclaw link list` OR a workspace store-chain child). Identity is sourced from the caller; writes + audit land in the target. Unknown project names throw — no silent fallback. The CLI exposes the same as `--project <name>` (mutually exclusive with `--cwd`). Example: `bclaw_get(entity="trap", id="trp#36", project="brainclaw-site")`. Cross-project `bclaw_coordinate` is inbox-only — auto-spawn is force-disabled because the spawn cwd / worktree are tied to the target repo; the target agent picks the brief up async via its own `bclaw_work`.',
|
|
386
|
+
'',
|
|
387
|
+
'**Session + claims:** `bclaw_session_start`, `bclaw_session_end`, `bclaw_claim`, `bclaw_release_claim`',
|
|
388
|
+
'**Plan steps:** `bclaw_add_step`, `bclaw_complete_step`, `bclaw_update_step`, `bclaw_delete_step`',
|
|
389
|
+
'**Inbox + handoffs:** `bclaw_read_inbox`, `bclaw_ack_message`, `bclaw_send_message`, `bclaw_correct_handoff`',
|
|
390
|
+
'**Notes + search:** `bclaw_write_note`, `bclaw_quick_capture`, `bclaw_search`',
|
|
391
|
+
'**Escalation (orchestrator path):**',
|
|
392
|
+
'- Review / consult / assign another agent → `bclaw_coordinate(intent=review|consult|assign)` (use `open_loop=true` on review to also dispatch the reviewer turn)',
|
|
393
|
+
'- Parallel execute across a sequence\'s lanes → `bclaw_dispatch(intent=execute)`',
|
|
394
|
+
'- Drive your turn in an already-opened loop → `bclaw_loop(intent=turn|complete_turn|advance|close)`',
|
|
395
|
+
'**Setup + navigation:** `bclaw_setup`, `bclaw_bootstrap`, `bclaw_switch`, `bclaw_release_notes`',
|
|
396
|
+
'',
|
|
397
|
+
'Legacy per-entity tools (`bclaw_list_plans`, `bclaw_accept`, `bclaw_get_context`, `bclaw_dispatch_review`, …) were removed from the catalog at v1.0 — direct calls still succeed as a migration escape hatch but emit a redirect warning. See `docs/integrations/mcp.md` + `docs/concepts/mcp-governance.md` for the full catalog and stability contract; raw MCP clients can request advanced tools with `tools/list` params `{ catalog: "all" }`.',
|
|
398
|
+
].join('\n');
|
|
399
|
+
}
|
|
400
|
+
// ─── Live section renderers ─────────────────────────────────────────────────
|
|
230
401
|
function renderTopTraps(state, limit) {
|
|
231
402
|
const traps = state.known_traps
|
|
232
403
|
.filter((t) => t.visibility === 'shared' && (!t.status || t.status === 'active') && !t.platform_scope)
|
|
@@ -262,6 +433,42 @@ function renderActivePlans(state, limit) {
|
|
|
262
433
|
}),
|
|
263
434
|
].join('\n');
|
|
264
435
|
}
|
|
436
|
+
function renderActiveClaimsFromInput(input) {
|
|
437
|
+
const claims = input.activeClaims;
|
|
438
|
+
if (!claims || claims.length === 0)
|
|
439
|
+
return undefined;
|
|
440
|
+
return [
|
|
441
|
+
'## brainclaw — active claims',
|
|
442
|
+
'',
|
|
443
|
+
...claims.map((c) => `- ${c.scope} (by ${c.agent ?? 'unknown'})`),
|
|
444
|
+
].join('\n');
|
|
445
|
+
}
|
|
446
|
+
function renderPendingCandidates(input) {
|
|
447
|
+
const candidates = input.pendingCandidates;
|
|
448
|
+
if (!candidates || candidates.length === 0)
|
|
449
|
+
return undefined;
|
|
450
|
+
return [
|
|
451
|
+
'## brainclaw — open candidates',
|
|
452
|
+
'',
|
|
453
|
+
...candidates.slice(0, 5).map((c) => `- [${c.type}] ${c.text} (by ${c.author ?? 'unknown'})`),
|
|
454
|
+
].join('\n');
|
|
455
|
+
}
|
|
456
|
+
function renderOpenHandoffs(state, limit) {
|
|
457
|
+
const handoffs = state.open_handoffs
|
|
458
|
+
.filter((h) => !h.status || h.status === 'open')
|
|
459
|
+
.slice(-limit)
|
|
460
|
+
.reverse();
|
|
461
|
+
if (handoffs.length === 0)
|
|
462
|
+
return undefined;
|
|
463
|
+
return [
|
|
464
|
+
'## brainclaw — open handoffs',
|
|
465
|
+
'',
|
|
466
|
+
...handoffs.map((h) => {
|
|
467
|
+
const plan = h.plan_id ? ` (${h.plan_id})` : '';
|
|
468
|
+
return `- ${h.from ?? 'unknown'} -> ${h.to ?? 'unknown'}${plan}: ${h.text}`;
|
|
469
|
+
}),
|
|
470
|
+
].join('\n');
|
|
471
|
+
}
|
|
265
472
|
function renderRecentDecisions(state) {
|
|
266
473
|
const decisions = state.recent_decisions.slice(-5);
|
|
267
474
|
if (decisions.length === 0)
|
|
@@ -301,6 +508,7 @@ function formatForAgent(agentName) {
|
|
|
301
508
|
case 'windsurf': return 'windsurf';
|
|
302
509
|
case 'cline': return 'cline';
|
|
303
510
|
case 'roo': return 'roo';
|
|
511
|
+
case 'kilocode': return 'kilocode';
|
|
304
512
|
case 'continue': return 'continue';
|
|
305
513
|
default: return 'agents-md';
|
|
306
514
|
}
|