brainclaw 1.5.4 → 1.6.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 +52 -28
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli.js +159 -12
- package/dist/commands/assignment-resource.js +182 -0
- package/dist/commands/bootstrap-loop.js +206 -0
- package/dist/commands/init.js +158 -22
- package/dist/commands/loop.js +156 -0
- package/dist/commands/loops-handlers.js +110 -55
- package/dist/commands/mcp-read-handlers.js +45 -4
- package/dist/commands/mcp.js +628 -205
- package/dist/commands/questions.js +180 -0
- package/dist/commands/reply.js +190 -0
- package/dist/commands/session-end.js +105 -3
- package/dist/commands/session-start.js +32 -53
- package/dist/commands/setup.js +87 -48
- package/dist/commands/switch.js +21 -1
- package/dist/core/agentrun-reconciler.js +65 -0
- package/dist/core/agentruns.js +10 -0
- package/dist/core/assignments.js +29 -10
- package/dist/core/claims.js +29 -0
- package/dist/core/context.js +1 -1
- package/dist/core/coordination.js +1 -1
- package/dist/core/dispatch-status.js +219 -0
- package/dist/core/entity-operations.js +166 -10
- package/dist/core/entity-registry.js +11 -10
- package/dist/core/execution-adapters.js +38 -2
- package/dist/core/facade-schema.js +55 -0
- package/dist/core/federation-cloud.js +27 -12
- package/dist/core/federation-materialize.js +57 -0
- package/dist/core/instruction-templates.js +2 -0
- package/dist/core/loops/bootstrap-acquire.js +195 -0
- package/dist/core/loops/facade-schema.js +68 -1
- package/dist/core/loops/hooks/bootstrap-write.js +144 -0
- package/dist/core/loops/hooks/notify-operator.js +148 -0
- package/dist/core/loops/hooks/survey-source-reader.js +256 -0
- package/dist/core/loops/index.js +8 -2
- package/dist/core/loops/next-expected.js +63 -0
- package/dist/core/loops/presets/bootstrap.js +75 -0
- package/dist/core/loops/presets/index.js +16 -0
- package/dist/core/loops/store.js +224 -4
- package/dist/core/loops/types.js +346 -1
- package/dist/core/loops/verbs.js +739 -6
- package/dist/core/schema.js +31 -2
- package/dist/core/state.js +62 -0
- package/dist/core/store-resolution.js +26 -16
- package/dist/facts.js +7 -5
- package/dist/facts.json +6 -4
- package/docs/cli.md +115 -30
- package/docs/concepts/dispatch-lifecycle.md +228 -0
- package/docs/concepts/loop-engine.md +55 -0
- package/docs/concepts/multi-agent-workflows.md +167 -166
- package/docs/concepts/troubleshooting.md +10 -2
- package/docs/integrations/agents.md +14 -14
- package/docs/integrations/codex.md +15 -12
- package/docs/integrations/mcp.md +10 -4
- package/docs/integrations/overview.md +11 -0
- package/docs/playbooks/productivity/index.md +3 -3
- package/docs/quickstart-existing-project.md +48 -28
- package/docs/quickstart.md +42 -28
- package/package.json +1 -1
package/dist/core/schema.js
CHANGED
|
@@ -232,6 +232,17 @@ export const HandoffSchema = z.object({
|
|
|
232
232
|
*/
|
|
233
233
|
superseded_by: z.string().optional(),
|
|
234
234
|
supersedes: z.string().optional(),
|
|
235
|
+
/**
|
|
236
|
+
* pln#365 finalization: opt-in cloud federation. Optional (no default) so
|
|
237
|
+
* existing on-disk handoffs without the field continue to parse, AND so
|
|
238
|
+
* an unset value means "stay local" rather than "implicitly shared". To
|
|
239
|
+
* opt a handoff into cloud push, set `visibility: 'shared'` explicitly
|
|
240
|
+
* when building it. Session-end push uses literal `visibility === 'shared'`
|
|
241
|
+
* (cf. session-end.ts:isExplicitlyShared). Risk it mitigates: a session
|
|
242
|
+
* handoff with `snapshot.diff` carrying secrets would otherwise leak the
|
|
243
|
+
* moment cloud_sync flips on, by virtue of being created at all.
|
|
244
|
+
*/
|
|
245
|
+
visibility: MemoryVisibilitySchema.optional(),
|
|
235
246
|
});
|
|
236
247
|
export const PlanStatusSchema = z.enum(['todo', 'in_progress', 'blocked', 'done', 'dropped']);
|
|
237
248
|
export const PlanStepStatusSchema = z.enum(['todo', 'in_progress', 'testing', 'done', 'blocked']);
|
|
@@ -243,7 +254,8 @@ export const PlanStepSchema = z.object({
|
|
|
243
254
|
created_at: z.string(),
|
|
244
255
|
updated_at: z.string(),
|
|
245
256
|
});
|
|
246
|
-
export const
|
|
257
|
+
export const PlanTypeEnumSchema = z.enum(['feat', 'fix', 'chore', 'spike', 'doc']);
|
|
258
|
+
export const PlanTypeSchema = PlanTypeEnumSchema.default('feat');
|
|
247
259
|
export const PlanItemSchema = z.object({
|
|
248
260
|
schema_version: z.number().int().positive().optional(),
|
|
249
261
|
id: z.string(),
|
|
@@ -532,6 +544,13 @@ export const CandidateSchema = z.preprocess(candidatePreprocess, z.object({
|
|
|
532
544
|
resolved_by: z.string().optional(),
|
|
533
545
|
resolution_reason: z.string().optional(),
|
|
534
546
|
provenance: ProvenancePassthroughSchema,
|
|
547
|
+
/**
|
|
548
|
+
* pln#365 finalization: opt-in cloud federation. Mirrors HandoffSchema —
|
|
549
|
+
* optional (no default) so unset means "stay local" and an agent must
|
|
550
|
+
* explicitly set `visibility: 'shared'` to opt a candidate into cloud
|
|
551
|
+
* push. Conservative because candidate.text can carry secrets.
|
|
552
|
+
*/
|
|
553
|
+
visibility: MemoryVisibilitySchema.optional(),
|
|
535
554
|
}));
|
|
536
555
|
export const ReflectiveMemoryConfigSchema = z.object({
|
|
537
556
|
enabled: z.boolean().default(true),
|
|
@@ -598,6 +617,7 @@ export const AssignmentStatusSchema = z.enum([
|
|
|
598
617
|
'accepted', // Worker acknowledged receipt
|
|
599
618
|
'started', // Worker reports active work begun
|
|
600
619
|
'completed', // Worker reports successful completion
|
|
620
|
+
'cancelled', // Supervisor/admin aborted the assignment explicitly
|
|
601
621
|
'failed', // Worker reports failure
|
|
602
622
|
'blocked', // Worker reports external blocker
|
|
603
623
|
'timed_out', // Sweeper detected no heartbeat within TTL
|
|
@@ -642,6 +662,7 @@ export const AssignmentSchema = z.object({
|
|
|
642
662
|
accepted_at: z.string().optional(),
|
|
643
663
|
started_at: z.string().optional(),
|
|
644
664
|
completed_at: z.string().optional(),
|
|
665
|
+
cancelled_at: z.string().optional(),
|
|
645
666
|
failed_at: z.string().optional(),
|
|
646
667
|
blocked_at: z.string().optional(),
|
|
647
668
|
timed_out_at: z.string().optional(),
|
|
@@ -754,6 +775,7 @@ export const ActionRequiredSchema = z.object({
|
|
|
754
775
|
tags: TagsWithDefaultSchema,
|
|
755
776
|
});
|
|
756
777
|
// --- Runtime notes schemas ---
|
|
778
|
+
export const RuntimeNoteTypeSchema = z.enum(['observation', 'session_start', 'session_end']);
|
|
757
779
|
export const RuntimeNoteSchema = z.object({
|
|
758
780
|
schema_version: z.number().int().positive().optional(),
|
|
759
781
|
id: z.string(),
|
|
@@ -769,7 +791,7 @@ export const RuntimeNoteSchema = z.object({
|
|
|
769
791
|
visibility: MemoryVisibilitySchema.default('shared'),
|
|
770
792
|
host_id: z.string().optional(),
|
|
771
793
|
expires_at: z.string().optional(),
|
|
772
|
-
note_type:
|
|
794
|
+
note_type: RuntimeNoteTypeSchema.default('observation'),
|
|
773
795
|
model: z.string().optional(),
|
|
774
796
|
provenance: ProvenancePassthroughSchema,
|
|
775
797
|
});
|
|
@@ -814,6 +836,7 @@ export const RuntimeEventTypeSchema = z.enum([
|
|
|
814
836
|
'assignment_started',
|
|
815
837
|
'assignment_progress',
|
|
816
838
|
'assignment_completed',
|
|
839
|
+
'assignment_cancelled',
|
|
817
840
|
'assignment_failed',
|
|
818
841
|
'assignment_blocked',
|
|
819
842
|
'assignment_timed_out',
|
|
@@ -934,6 +957,11 @@ export const RemoteSyncSchema = z.object({
|
|
|
934
957
|
ssh_key_path: z.string().optional(),
|
|
935
958
|
sync_strategy: z.enum(['pull-only', 'push-pull', 'pr-based']).default('push-pull'),
|
|
936
959
|
});
|
|
960
|
+
export const CloudSyncConfigSchema = z.object({
|
|
961
|
+
enabled: z.boolean().default(false),
|
|
962
|
+
endpoint: z.string().default('https://app.brainclaw.dev'),
|
|
963
|
+
api_key: z.string().optional(),
|
|
964
|
+
});
|
|
937
965
|
export const SessionSnapshotSchema = z.object({
|
|
938
966
|
schema_version: z.number().int().positive().optional(),
|
|
939
967
|
session_id: z.string(),
|
|
@@ -1229,6 +1257,7 @@ export const ConfigSchema = z.object({
|
|
|
1229
1257
|
target_audience: z.enum(['human', 'agent']).optional().default('human'),
|
|
1230
1258
|
openclaw_bridge: z.boolean().optional().default(false),
|
|
1231
1259
|
remote_sync: RemoteSyncSchema.optional(),
|
|
1260
|
+
cloud_sync: CloudSyncConfigSchema.optional(),
|
|
1232
1261
|
telemetry: z.literal(false),
|
|
1233
1262
|
allow_network: z.literal(false),
|
|
1234
1263
|
redaction: RedactionConfigSchema,
|
package/dist/core/state.js
CHANGED
|
@@ -37,6 +37,68 @@ function loadDirectoryItems(dirPath, schema, documentType) {
|
|
|
37
37
|
}
|
|
38
38
|
return items;
|
|
39
39
|
}
|
|
40
|
+
const ENTITY_LOAD_CONFIG = {
|
|
41
|
+
constraint: { subdir: 'constraints', documentType: 'constraint', recursive: false },
|
|
42
|
+
decision: { subdir: 'decisions', documentType: 'decision', recursive: false },
|
|
43
|
+
trap: { subdir: 'traps', documentType: 'trap', recursive: false },
|
|
44
|
+
handoff: { subdir: 'handoffs', documentType: 'handoff', recursive: false },
|
|
45
|
+
plan: { subdir: 'plans', documentType: 'plan', recursive: false },
|
|
46
|
+
candidate: { subdir: 'inbox', documentType: 'candidate', recursive: false },
|
|
47
|
+
claim: { subdir: 'claims', documentType: 'claim', recursive: false },
|
|
48
|
+
assignment: { subdir: 'assignments', documentType: 'assignment', recursive: false },
|
|
49
|
+
agent_run: { subdir: 'runs', documentType: 'agent_run', recursive: false },
|
|
50
|
+
action: { subdir: 'actions', documentType: 'action_required', recursive: false },
|
|
51
|
+
runtime_note: { subdir: 'runtime', documentType: 'runtime_note', recursive: true },
|
|
52
|
+
};
|
|
53
|
+
function listJsonFiles(dirPath, recursive) {
|
|
54
|
+
if (!fs.existsSync(dirPath))
|
|
55
|
+
return [];
|
|
56
|
+
const files = [];
|
|
57
|
+
for (const entry of fs.readdirSync(dirPath).sort()) {
|
|
58
|
+
const fullPath = path.join(dirPath, entry);
|
|
59
|
+
const stat = fs.statSync(fullPath);
|
|
60
|
+
if (stat.isDirectory()) {
|
|
61
|
+
if (recursive)
|
|
62
|
+
files.push(...listJsonFiles(fullPath, true));
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (entry.endsWith('.json'))
|
|
66
|
+
files.push(fullPath);
|
|
67
|
+
}
|
|
68
|
+
return files;
|
|
69
|
+
}
|
|
70
|
+
function validationErrorsFrom(error) {
|
|
71
|
+
if (error && typeof error === 'object' && 'issues' in error && Array.isArray(error.issues)) {
|
|
72
|
+
return (error.issues).map((issue) => {
|
|
73
|
+
const issuePath = Array.isArray(issue.path) && issue.path.length > 0 ? `${issue.path.join('.')}: ` : '';
|
|
74
|
+
return `${issuePath}${issue.message ?? 'validation failed'}`;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return [error instanceof Error ? error.message : String(error)];
|
|
78
|
+
}
|
|
79
|
+
export function collectLoadValidationWarnings(entity, cwd) {
|
|
80
|
+
const config = ENTITY_LOAD_CONFIG[entity];
|
|
81
|
+
if (!config)
|
|
82
|
+
return [];
|
|
83
|
+
const effectiveCwd = cwd ?? process.cwd();
|
|
84
|
+
const dirPath = resolveEntityDir(config.subdir, effectiveCwd, 'read');
|
|
85
|
+
return listJsonFiles(dirPath, config.recursive).flatMap((filepath) => {
|
|
86
|
+
try {
|
|
87
|
+
loadVersionedJsonFile(config.documentType, filepath);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return [{
|
|
92
|
+
entity_id: path.basename(filepath, '.json'),
|
|
93
|
+
validation_errors: validationErrorsFrom(error),
|
|
94
|
+
path: filepath,
|
|
95
|
+
}];
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export function findLoadValidationWarning(entity, id, cwd) {
|
|
100
|
+
return collectLoadValidationWarnings(entity, cwd).find((warning) => warning.entity_id === id);
|
|
101
|
+
}
|
|
40
102
|
export function loadState(cwd) {
|
|
41
103
|
// Load from entity-aligned directories (with legacy fallback)
|
|
42
104
|
const effectiveCwd = cwd ?? process.cwd();
|
|
@@ -91,48 +91,53 @@ export function resolveTargetStore(cwd = process.cwd(), target = 'local', option
|
|
|
91
91
|
*
|
|
92
92
|
* Priority:
|
|
93
93
|
* 1. explicitCwd (--cwd flag)
|
|
94
|
-
* 2. BRAINCLAW_CWD env var →
|
|
95
|
-
* 3. BRAINCLAW_PROJECT env var → resolved by name/path from workspace
|
|
96
|
-
* 4. Session-scoped active project (from .current-session)
|
|
94
|
+
* 2. BRAINCLAW_CWD env var → workspace anchor injected by MCP configs
|
|
95
|
+
* 3. BRAINCLAW_PROJECT env var → resolved by name/path from workspace anchor
|
|
96
|
+
* 4. Session-scoped active project (from .current-session under the anchor)
|
|
97
97
|
* 5. Global active-project.json in workspace root
|
|
98
|
-
* 6. process.cwd()
|
|
98
|
+
* 6. Workspace anchor or process.cwd()
|
|
99
99
|
*/
|
|
100
100
|
export function resolveEffectiveCwd(options = {}) {
|
|
101
|
+
const baseCwd = path.resolve(options.baseCwd ?? process.cwd());
|
|
101
102
|
// 1. Explicit --cwd flag
|
|
102
103
|
if (options.explicitCwd) {
|
|
103
104
|
return path.resolve(options.explicitCwd);
|
|
104
105
|
}
|
|
105
|
-
// 2. BRAINCLAW_CWD env var — set by MCP configs to
|
|
106
|
-
// regardless of the IDE's process.cwd() at launch time
|
|
106
|
+
// 2. BRAINCLAW_CWD env var — set by MCP configs to anchor resolution to the
|
|
107
|
+
// workspace regardless of the IDE's process.cwd() at launch time. It is a
|
|
108
|
+
// workspace anchor, not the final answer: session/global active project
|
|
109
|
+
// state still overrides it.
|
|
110
|
+
let anchorCwd = baseCwd;
|
|
107
111
|
const envCwd = process.env.BRAINCLAW_CWD?.trim();
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
const hasEnvWorkspace = !!envCwd && fs.existsSync(path.join(path.resolve(envCwd), MEMORY_DIR, 'config.yaml'));
|
|
113
|
+
if (hasEnvWorkspace) {
|
|
114
|
+
anchorCwd = path.resolve(envCwd);
|
|
110
115
|
}
|
|
111
116
|
// 3. BRAINCLAW_PROJECT env var
|
|
112
117
|
const envProject = process.env.BRAINCLAW_PROJECT;
|
|
113
118
|
if (envProject) {
|
|
114
|
-
const resolved = resolveProjectRef(envProject,
|
|
119
|
+
const resolved = resolveProjectRef(envProject, anchorCwd, options.storeChainOptions);
|
|
115
120
|
if (resolved)
|
|
116
121
|
return resolved;
|
|
117
122
|
}
|
|
118
|
-
//
|
|
119
|
-
const session = loadCurrentSession(
|
|
123
|
+
// 4. Session-scoped active project (per-agent, no cross-agent interference)
|
|
124
|
+
const session = loadCurrentSession(anchorCwd);
|
|
120
125
|
if (session?.active_project) {
|
|
121
126
|
const sp = session.active_project;
|
|
122
127
|
if (fs.existsSync(path.join(sp.path, MEMORY_DIR, 'config.yaml'))) {
|
|
123
128
|
return sp.path;
|
|
124
129
|
}
|
|
125
130
|
}
|
|
126
|
-
//
|
|
127
|
-
const wsRoot = resolveWorkspaceRoot(
|
|
131
|
+
// 5. Global active-project.json from workspace root
|
|
132
|
+
const wsRoot = hasEnvWorkspace ? anchorCwd : resolveWorkspaceRoot(anchorCwd, options.storeChainOptions);
|
|
128
133
|
if (wsRoot) {
|
|
129
134
|
const active = loadActiveProject(wsRoot);
|
|
130
135
|
if (active && fs.existsSync(path.join(active.path, MEMORY_DIR, 'config.yaml'))) {
|
|
131
136
|
return active.path;
|
|
132
137
|
}
|
|
133
138
|
}
|
|
134
|
-
//
|
|
135
|
-
return
|
|
139
|
+
// 6. Default
|
|
140
|
+
return anchorCwd;
|
|
136
141
|
}
|
|
137
142
|
/**
|
|
138
143
|
* Find the workspace root (farthest store in the chain, or the one with
|
|
@@ -150,9 +155,14 @@ export function resolveWorkspaceRoot(cwd = process.cwd(), options = {}) {
|
|
|
150
155
|
* Returns undefined when the reference cannot be resolved to a valid brainclaw project.
|
|
151
156
|
*/
|
|
152
157
|
export function resolveProjectRef(ref, cwd = process.cwd(), storeChainOptions) {
|
|
158
|
+
const envWorkspace = process.env.BRAINCLAW_CWD?.trim();
|
|
159
|
+
const workspaceAnchor = envWorkspace && fs.existsSync(path.join(path.resolve(envWorkspace), MEMORY_DIR, 'config.yaml'))
|
|
160
|
+
? path.resolve(envWorkspace)
|
|
161
|
+
: undefined;
|
|
153
162
|
// Walk UP from real cwd to find the outermost .brainclaw/ — this avoids
|
|
154
163
|
// circular resolution when an active project narrows the workspace view.
|
|
155
|
-
const wsRoot =
|
|
164
|
+
const wsRoot = workspaceAnchor
|
|
165
|
+
?? findOutermostBrainclawRoot(cwd)
|
|
156
166
|
?? resolveWorkspaceRoot(cwd, storeChainOptions);
|
|
157
167
|
if (!wsRoot)
|
|
158
168
|
return undefined;
|
package/dist/facts.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Generated by scripts/emit-site-facts.mjs at build time. Do not edit manually.
|
|
2
|
-
// Source: brainclaw v1.
|
|
2
|
+
// Source: brainclaw v1.6.0 on 2026-05-22T22:24:08.363Z
|
|
3
3
|
export const FACTS = {
|
|
4
|
-
"version": "1.
|
|
5
|
-
"generated_at": "2026-05-
|
|
4
|
+
"version": "1.6.0",
|
|
5
|
+
"generated_at": "2026-05-22T22:24:08.363Z",
|
|
6
6
|
"tools": {
|
|
7
|
-
"count":
|
|
8
|
-
"published_count":
|
|
7
|
+
"count": 62,
|
|
8
|
+
"published_count": 61,
|
|
9
9
|
"names": [
|
|
10
10
|
"bclaw_bootstrap",
|
|
11
11
|
"bclaw_release_notes",
|
|
@@ -30,10 +30,12 @@ export const FACTS = {
|
|
|
30
30
|
"bclaw_check_security",
|
|
31
31
|
"bclaw_read_inbox",
|
|
32
32
|
"bclaw_get_thread",
|
|
33
|
+
"bclaw_dispatch_status",
|
|
33
34
|
"bclaw_dispatch",
|
|
34
35
|
"bclaw_send_message",
|
|
35
36
|
"bclaw_ack_message",
|
|
36
37
|
"bclaw_setup",
|
|
38
|
+
"bclaw_init_project",
|
|
37
39
|
"bclaw_write_note",
|
|
38
40
|
"bclaw_quick_capture",
|
|
39
41
|
"bclaw_claim",
|
package/dist/facts.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
3
|
-
"generated_at": "2026-05-
|
|
2
|
+
"version": "1.6.0",
|
|
3
|
+
"generated_at": "2026-05-22T22:24:08.363Z",
|
|
4
4
|
"tools": {
|
|
5
|
-
"count":
|
|
6
|
-
"published_count":
|
|
5
|
+
"count": 62,
|
|
6
|
+
"published_count": 61,
|
|
7
7
|
"names": [
|
|
8
8
|
"bclaw_bootstrap",
|
|
9
9
|
"bclaw_release_notes",
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
"bclaw_check_security",
|
|
29
29
|
"bclaw_read_inbox",
|
|
30
30
|
"bclaw_get_thread",
|
|
31
|
+
"bclaw_dispatch_status",
|
|
31
32
|
"bclaw_dispatch",
|
|
32
33
|
"bclaw_send_message",
|
|
33
34
|
"bclaw_ack_message",
|
|
34
35
|
"bclaw_setup",
|
|
36
|
+
"bclaw_init_project",
|
|
35
37
|
"bclaw_write_note",
|
|
36
38
|
"bclaw_quick_capture",
|
|
37
39
|
"bclaw_claim",
|
package/docs/cli.md
CHANGED
|
@@ -62,9 +62,9 @@ brainclaw --cwd /other/path status # one-off override without switching
|
|
|
62
62
|
|
|
63
63
|
## Initialize and Inspect
|
|
64
64
|
|
|
65
|
-
### `brainclaw setup`
|
|
66
|
-
|
|
67
|
-
Global onboarding wizard — detects AI agents, installs global Brainclaw prerequisites,
|
|
65
|
+
### `brainclaw setup`
|
|
66
|
+
|
|
67
|
+
Global onboarding wizard — bootstraps the machine, detects AI agents, installs global Brainclaw prerequisites, writes agent/MCP config, gitignores generated workspace-local integration files, and initialises multiple repositories in one pass. It scans each root itself plus its direct child repositories, and ignores internal Brainclaw memory repos such as `.brainclaw/`.
|
|
68
68
|
|
|
69
69
|
| Option | Description |
|
|
70
70
|
|---|---|
|
|
@@ -80,32 +80,57 @@ brainclaw setup --roots ~/Projects --agents detected # scan ~/Projects, confi
|
|
|
80
80
|
brainclaw setup --roots ~/Projects,~/work --agents all # all agents, multiple roots
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
**MCP usage (agent-driven):** Use `bclaw_setup` with the resume pattern — call without `step` to start, then pass `step` + `choice` to advance through each stage (`project_roots` → `repo_selection` → `agent_selection`).
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
### `brainclaw
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
| Option | Description |
|
|
92
|
-
|---|---|
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
83
|
+
**MCP usage (agent-driven):** Use `bclaw_setup` with the resume pattern — call without `step` to start, then pass `step` + `choice` to advance through each stage (`project_roots` → `repo_selection` → `agent_selection`).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### `brainclaw setup-machine`
|
|
88
|
+
|
|
89
|
+
Machine-only onboarding. Detects available agents, writes the machine-level MCP/user config Brainclaw manages, refreshes machine inventory, and stops there — no repository scan, no `.brainclaw/` init in the current working tree.
|
|
90
|
+
|
|
91
|
+
| Option | Description |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `--agents <agents>` | Agents to configure: `all`, `detected`, or comma-separated names |
|
|
94
|
+
| `-y, --yes` | Accept all defaults non-interactively |
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
brainclaw setup-machine
|
|
98
|
+
brainclaw setup-machine --yes
|
|
99
|
+
brainclaw setup-machine --agents codex,cursor
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Use this when Brainclaw is new on the current machine and you want to make the MCP surface visible to your coding agent before touching any project. The usual follow-up is `brainclaw init` inside the project you want to create or refresh.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### `brainclaw init`
|
|
107
|
+
|
|
108
|
+
Create or refresh Brainclaw state for the current project root. Detects the AI agent environment, writes or refreshes its native instruction file, and installs a git post-merge hook for automatic claim release. `init` is now safe to rerun on an already initialized project: it preserves canonical memory and refreshes the managed Brainclaw and detected-agent files. Do not run `init` from inside `.brainclaw/`; that directory is Brainclaw's own memory store, not a project root.
|
|
109
|
+
|
|
110
|
+
| Option | Description |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `-y, --yes` | Non-interactive, accept all defaults |
|
|
113
|
+
| `--force` | Rebuild managed initialization from Brainclaw defaults while preserving canonical memory data |
|
|
114
|
+
| `--compact` | Generate a compact instruction file |
|
|
115
|
+
| `--topology <value>` | Storage topology (e.g. `sidecar` to store outside the repo) |
|
|
116
|
+
| `--project-mode <value>` | Project mode (e.g. `multi-project`) |
|
|
98
117
|
| `--project-strategy <value>` | Project strategy (e.g. `folder`) |
|
|
99
118
|
| `--no-analyze-repo` | Skip automatic repository analysis |
|
|
100
119
|
| `--scan` | Scan repository for existing conventions |
|
|
101
120
|
|
|
102
121
|
```bash
|
|
103
|
-
brainclaw init
|
|
104
|
-
brainclaw init -y
|
|
105
|
-
brainclaw init --force
|
|
106
|
-
brainclaw init --topology sidecar
|
|
107
|
-
brainclaw init --project-mode multi-project --project-strategy folder
|
|
108
|
-
```
|
|
122
|
+
brainclaw init
|
|
123
|
+
brainclaw init -y
|
|
124
|
+
brainclaw init --force
|
|
125
|
+
brainclaw init --topology sidecar
|
|
126
|
+
brainclaw init --project-mode multi-project --project-strategy folder
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Common onboarding split:
|
|
130
|
+
|
|
131
|
+
- new machine → `brainclaw setup-machine --yes`
|
|
132
|
+
- current project (new or already using Brainclaw) → `brainclaw init`
|
|
133
|
+
- explicit second agent on an existing Brainclaw project → `brainclaw enable-agent <agent-name>`
|
|
109
134
|
|
|
110
135
|
### `brainclaw machine-profile`
|
|
111
136
|
|
|
@@ -758,9 +783,29 @@ brainclaw claim list --agent copilot --project auth
|
|
|
758
783
|
brainclaw claim list --all --json
|
|
759
784
|
```
|
|
760
785
|
|
|
761
|
-
Legacy alias: `brainclaw list-claims`
|
|
762
|
-
|
|
763
|
-
### `brainclaw list
|
|
786
|
+
Legacy alias: `brainclaw list-claims`
|
|
787
|
+
|
|
788
|
+
### `brainclaw assignment list`
|
|
789
|
+
|
|
790
|
+
List assignments. By default this shows only non-terminal assignments; use `--all` to include `completed`, `cancelled`, `expired`, and `rerouted`.
|
|
791
|
+
|
|
792
|
+
| Option | Description |
|
|
793
|
+
|---|---|
|
|
794
|
+
| `--json` | Output as JSON |
|
|
795
|
+
| `--all` | Include terminal assignments |
|
|
796
|
+
| `--status <status>` | Filter by assignment status |
|
|
797
|
+
| `--agent <name>` | Filter by agent |
|
|
798
|
+
| `--claim <id>` | Filter by claim ID |
|
|
799
|
+
| `--plan <id>` | Filter by plan ID |
|
|
800
|
+
| `--sequence <id>` | Filter by sequence ID |
|
|
801
|
+
|
|
802
|
+
```bash
|
|
803
|
+
brainclaw assignment list
|
|
804
|
+
brainclaw assignment list --status blocked
|
|
805
|
+
brainclaw assignment list --all --json
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### `brainclaw list-agents`
|
|
764
809
|
|
|
765
810
|
List registered agent and human identities.
|
|
766
811
|
|
|
@@ -1113,9 +1158,49 @@ brainclaw claim release clm_001
|
|
|
1113
1158
|
brainclaw claim release clm_001 --plan-status done
|
|
1114
1159
|
```
|
|
1115
1160
|
|
|
1116
|
-
Legacy alias: `brainclaw release-claim <id>`
|
|
1117
|
-
|
|
1118
|
-
### `brainclaw
|
|
1161
|
+
Legacy alias: `brainclaw release-claim <id>`
|
|
1162
|
+
|
|
1163
|
+
### `brainclaw assignment get <id>`
|
|
1164
|
+
|
|
1165
|
+
Show one assignment with its lifecycle timestamps and links.
|
|
1166
|
+
|
|
1167
|
+
| Option | Description |
|
|
1168
|
+
|---|---|
|
|
1169
|
+
| `--json` | Output as JSON |
|
|
1170
|
+
|
|
1171
|
+
```bash
|
|
1172
|
+
brainclaw assignment get asgn_001
|
|
1173
|
+
brainclaw assignment get asgn_001 --json
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
### `brainclaw assignment update <id>`
|
|
1177
|
+
|
|
1178
|
+
Advance an assignment to a supported lifecycle status through the canonical assignment FSM.
|
|
1179
|
+
|
|
1180
|
+
| Option | Description |
|
|
1181
|
+
|---|---|
|
|
1182
|
+
| `--status <status>` | Target assignment status |
|
|
1183
|
+
| `--reason <text>` | Optional status reason recorded on the assignment |
|
|
1184
|
+
|
|
1185
|
+
```bash
|
|
1186
|
+
brainclaw assignment update asgn_001 --status started
|
|
1187
|
+
brainclaw assignment update asgn_001 --status cancelled --reason "Supervisor aborted the lane"
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
### `brainclaw assignment cancel <id>`
|
|
1191
|
+
|
|
1192
|
+
Supervisor/admin shortcut for `brainclaw assignment update <id> --status cancelled`.
|
|
1193
|
+
|
|
1194
|
+
| Option | Description |
|
|
1195
|
+
|---|---|
|
|
1196
|
+
| `--reason <text>` | Optional cancellation reason recorded on the assignment |
|
|
1197
|
+
|
|
1198
|
+
```bash
|
|
1199
|
+
brainclaw assignment cancel asgn_001
|
|
1200
|
+
brainclaw assignment cancel asgn_001 --reason "Superseded by reroute"
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
### `brainclaw release-claims`
|
|
1119
1204
|
|
|
1120
1205
|
Release multiple claims derived from a Git diff.
|
|
1121
1206
|
|