brainclaw 0.19.11 → 0.19.14

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/dist/core/io.js CHANGED
@@ -30,6 +30,7 @@ const ENTITY_DIR_MAP = {
30
30
  'runtime': 'coordination/runtime',
31
31
  'runtime-hosts': 'coordination/runtime-hosts',
32
32
  'runtime-private': 'coordination/runtime-private',
33
+ 'surface-tasks': 'coordination/surface-tasks',
33
34
  // discovery/ — Project entity: what's available
34
35
  'bootstrap': 'discovery/bootstrap',
35
36
  'bootstrap/seeds': 'discovery/bootstrap/seeds',
@@ -4,6 +4,7 @@ import path from 'node:path';
4
4
  import { spawnSync } from 'node:child_process';
5
5
  import yaml from 'yaml';
6
6
  import { MEMORY_DIR } from './io.js';
7
+ import { buildAiSurfaceInventory, renderAiSurfaceSummary } from './ai-surface-inventory.js';
7
8
  // ── Detection Functions ────────────────────────────────────────────────────────
8
9
  const TOOLCHAINS = [
9
10
  { name: 'node', command: 'node', versionArgs: ['--version'] },
@@ -227,7 +228,7 @@ function detectWslDistros() {
227
228
  */
228
229
  export function buildMachineProfile() {
229
230
  return {
230
- schema_version: 1,
231
+ schema_version: 2,
231
232
  generated_at: new Date().toISOString(),
232
233
  hostname: os.hostname(),
233
234
  os_user: os.userInfo().username,
@@ -241,6 +242,7 @@ export function buildMachineProfile() {
241
242
  ssh_keys: detectSshKeys(),
242
243
  toolchains: detectToolchains(),
243
244
  wsl_distros: detectWslDistros(),
245
+ ai_surfaces: buildAiSurfaceInventory(),
244
246
  };
245
247
  }
246
248
  /**
@@ -283,6 +285,7 @@ export function loadMachineProfile() {
283
285
  */
284
286
  export function renderMachineProfileSummary(profile) {
285
287
  const lines = [];
288
+ const aiSurfaces = profile.ai_surfaces ?? [];
286
289
  lines.push(`Machine: ${profile.hostname} (user: ${profile.os_user})`);
287
290
  lines.push(`Home: ${profile.home_dir}`);
288
291
  lines.push(`OS: ${profile.os_variant} (${profile.platform} ${profile.os_release}, ${profile.arch})`);
@@ -326,6 +329,9 @@ export function renderMachineProfileSummary(profile) {
326
329
  lines.push(` - ${d.name}${d.default ? ' (default)' : ''}: ${nodeInfo}`);
327
330
  }
328
331
  }
332
+ if (aiSurfaces.length > 0) {
333
+ lines.push(...renderAiSurfaceSummary(aiSurfaces));
334
+ }
329
335
  lines.push(`Profile generated: ${profile.generated_at}`);
330
336
  return lines.join('\n');
331
337
  }
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import YAML from 'yaml';
4
4
  import { memoryDir, memoryPath, readFileSync, writeFileAtomic, resolveEntityDir } from './io.js';
5
- import { BootstrapApplicationReceiptSchema, BootstrapImportPlanDocumentSchema, AgentIdentityDocumentSchema, BootstrapProfileDocumentSchema, CandidateSchema, ClaimSchema, ConfigSchema, MemorySeedDocumentSchema, ConstraintSchema, CurrentSessionStateSchema, DecisionSchema, HandoffSchema, InstructionEntrySchema, PlanItemSchema, ProjectIdentityDocumentSchema, RuntimeNoteSchema, SessionSnapshotSchema, TrapSchema, } from './schema.js';
5
+ import { BootstrapApplicationReceiptSchema, BootstrapImportPlanDocumentSchema, AgentIdentityDocumentSchema, BootstrapProfileDocumentSchema, CandidateSchema, ClaimSchema, ConfigSchema, MemorySeedDocumentSchema, ConstraintSchema, CurrentSessionStateSchema, DecisionSchema, HandoffSchema, InstructionEntrySchema, PlanItemSchema, ProjectIdentityDocumentSchema, RuntimeNoteSchema, SessionSnapshotSchema, TrapSchema, AiSurfaceTaskRequestSchema, } from './schema.js';
6
6
  export class MigrationError extends Error {
7
7
  kind;
8
8
  documentType;
@@ -31,6 +31,7 @@ const registry = {
31
31
  plan: createRegistryEntry(PlanItemSchema),
32
32
  project_identity: createRegistryEntry(ProjectIdentityDocumentSchema),
33
33
  runtime_note: createRegistryEntry(RuntimeNoteSchema),
34
+ ai_surface_task: createRegistryEntry(AiSurfaceTaskRequestSchema),
34
35
  session_snapshot: createRegistryEntry(SessionSnapshotSchema),
35
36
  trap: createRegistryEntry(TrapSchema),
36
37
  };
@@ -164,6 +165,7 @@ export function scanMigrationStatus(cwd) {
164
165
  collectDirectory(entries, resolveEntityDir('runtime', effectiveCwd, 'read'), 'runtime_note', true);
165
166
  collectDirectory(entries, resolveEntityDir('runtime-hosts', effectiveCwd, 'read'), 'runtime_note', true);
166
167
  collectDirectory(entries, resolveEntityDir('runtime-private', effectiveCwd, 'read'), 'runtime_note', true);
168
+ collectDirectory(entries, resolveEntityDir('surface-tasks', effectiveCwd, 'read'), 'ai_surface_task');
167
169
  collectDirectory(entries, resolveEntityDir('instructions', effectiveCwd, 'read'), 'instruction');
168
170
  collectDirectory(entries, path.join(resolveEntityDir('bootstrap', effectiveCwd, 'read'), 'seeds'), 'memory_seed');
169
171
  collectDirectory(entries, resolveEntityDir('agents', effectiveCwd, 'read'), 'agent_identity');
@@ -344,6 +344,31 @@ export const RuntimeNoteSchema = z.object({
344
344
  expires_at: z.string().optional(),
345
345
  note_type: z.enum(['observation', 'session_start', 'session_end']).default('observation'),
346
346
  });
347
+ // --- AI surface task request schemas ---
348
+ export const AiSurfaceTaskStatusSchema = z.enum(['queued', 'in_progress', 'completed', 'cancelled', 'failed']);
349
+ export const AiSurfaceTaskKindSchema = z.enum(['visual_asset', 'draft', 'summary', 'analysis', 'research', 'custom']);
350
+ export const AiSurfaceTaskRequestSchema = z.object({
351
+ schema_version: z.number().int().positive().optional(),
352
+ id: z.string(),
353
+ short_label: z.string().optional(),
354
+ title: z.string(),
355
+ instructions: z.string(),
356
+ target_surface: z.string(),
357
+ kind: AiSurfaceTaskKindSchema.default('custom'),
358
+ created_at: z.string(),
359
+ updated_at: z.string(),
360
+ author: z.string(),
361
+ author_id: z.string().optional(),
362
+ project_id: z.string().optional(),
363
+ session_id: z.string().optional(),
364
+ status: AiSurfaceTaskStatusSchema.default('queued'),
365
+ requested_outputs: z.array(z.string()).default([]),
366
+ related_paths: z.array(z.string()).optional(),
367
+ tags: z.array(z.string()).default([]),
368
+ claimed_at: z.string().optional(),
369
+ completed_at: z.string().optional(),
370
+ result_note: z.string().optional(),
371
+ });
347
372
  // --- Runtime event schemas ---
348
373
  export const RuntimeEventTypeSchema = z.enum([
349
374
  'task_started',
@@ -0,0 +1,115 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { loadGlobalRegistry, scanProject } from './global-registry.js';
4
+ const SKIP_DIRS = new Set([
5
+ '.brainclaw',
6
+ '.git',
7
+ 'node_modules',
8
+ 'dist',
9
+ 'dist-test',
10
+ 'build',
11
+ 'coverage',
12
+ '.venv',
13
+ 'venv',
14
+ '__pycache__',
15
+ 'target',
16
+ 'vendor',
17
+ '.next',
18
+ '.nuxt',
19
+ ]);
20
+ export function summarizeWorkspaceProjects(cwd, config) {
21
+ const configuredProjects = config.projects?.known ?? [];
22
+ const usesFolderResolution = config.project_mode === 'multi-project' && (config.projects?.strategy ?? 'manual') === 'folder';
23
+ const discovered = new Map();
24
+ for (const name of configuredProjects) {
25
+ const key = `config:${name}`;
26
+ discovered.set(key, {
27
+ path: name,
28
+ relative_path: name,
29
+ project_name: name,
30
+ source: 'config',
31
+ });
32
+ }
33
+ if (usesFolderResolution) {
34
+ for (const project of collectRegistryProjectsUnder(cwd)) {
35
+ const normalized = path.resolve(project.path);
36
+ if (normalized === path.resolve(cwd)) {
37
+ continue;
38
+ }
39
+ discovered.set(`path:${normalized}`, {
40
+ path: normalized,
41
+ relative_path: path.relative(cwd, normalized) || '.',
42
+ project_id: project.project_id,
43
+ project_name: project.project_name,
44
+ source: 'registry',
45
+ });
46
+ }
47
+ for (const project of scanNestedBrainclawProjects(cwd)) {
48
+ const normalized = path.resolve(project.path);
49
+ if (normalized === path.resolve(cwd)) {
50
+ continue;
51
+ }
52
+ if (!discovered.has(`path:${normalized}`)) {
53
+ discovered.set(`path:${normalized}`, {
54
+ path: normalized,
55
+ relative_path: path.relative(cwd, normalized) || '.',
56
+ project_id: project.project_id,
57
+ project_name: project.project_name,
58
+ source: 'filesystem',
59
+ });
60
+ }
61
+ }
62
+ }
63
+ return {
64
+ strategy: config.projects?.strategy ?? 'manual',
65
+ configured_projects: configuredProjects,
66
+ discovered_projects: [...discovered.values()].sort((a, b) => a.relative_path.localeCompare(b.relative_path)),
67
+ effective_project_count: discovered.size,
68
+ uses_folder_resolution: usesFolderResolution,
69
+ };
70
+ }
71
+ export function scanNestedBrainclawProjects(rootDir, maxDepth = 6) {
72
+ const resolvedRoot = path.resolve(rootDir);
73
+ const results = new Map();
74
+ function walk(dir, depth) {
75
+ if (depth > maxDepth) {
76
+ return;
77
+ }
78
+ let entries;
79
+ try {
80
+ entries = fs.readdirSync(dir, { withFileTypes: true });
81
+ }
82
+ catch {
83
+ return;
84
+ }
85
+ for (const entry of entries) {
86
+ if (!entry.isDirectory())
87
+ continue;
88
+ if (SKIP_DIRS.has(entry.name))
89
+ continue;
90
+ if (entry.name.startsWith('.') && entry.name !== '.brainclaw')
91
+ continue;
92
+ const childDir = path.join(dir, entry.name);
93
+ const maybeProject = scanProject(childDir);
94
+ if (maybeProject) {
95
+ results.set(path.resolve(maybeProject.path), maybeProject);
96
+ }
97
+ walk(childDir, depth + 1);
98
+ }
99
+ }
100
+ walk(resolvedRoot, 1);
101
+ return [...results.values()].sort((a, b) => a.path.localeCompare(b.path));
102
+ }
103
+ function collectRegistryProjectsUnder(rootDir) {
104
+ const registry = loadGlobalRegistry();
105
+ if (!registry) {
106
+ return [];
107
+ }
108
+ const resolvedRoot = path.resolve(rootDir);
109
+ return registry.projects.filter((project) => isWithinRoot(project.path, resolvedRoot));
110
+ }
111
+ function isWithinRoot(candidatePath, rootDir) {
112
+ const relative = path.relative(rootDir, path.resolve(candidatePath));
113
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
114
+ }
115
+ //# sourceMappingURL=workspace-projects.js.map
package/docs/cli.md CHANGED
@@ -60,6 +60,85 @@ brainclaw init --topology sidecar
60
60
  brainclaw init --project-mode multi-project --project-strategy folder
61
61
  ```
62
62
 
63
+ ### `brainclaw machine-profile`
64
+
65
+ Detect and persist machine-level capabilities, including other local AI work surfaces on the same machine.
66
+
67
+ This is the inventory Brainclaw uses to distinguish coding agents from desktop AI apps or adjacent surfaces such as:
68
+
69
+ - `ChatGPT Desktop`
70
+ - `Claude Desktop`
71
+ - `Claude Cowork`
72
+ - `Gemini Web`
73
+ - `Gemini CLI / Antigravity`
74
+
75
+ | Option | Description |
76
+ |---|---|
77
+ | `--refresh` | Force regeneration even if a cached profile already exists |
78
+ | `--json` | Output as JSON |
79
+
80
+ ```bash
81
+ brainclaw machine-profile
82
+ brainclaw machine-profile --refresh
83
+ brainclaw machine-profile --refresh --json
84
+ ```
85
+
86
+ Use this when you want Brainclaw to detect what AI work surfaces are actually available on the current machine before choosing an onboarding path or queueing work for another surface.
87
+
88
+ ### `brainclaw upgrade`
89
+
90
+ Upgrade the local Brainclaw store layout and refresh managed agent files when a release changes persisted schema or generated workspace integrations.
91
+
92
+ | Option | Description |
93
+ |---|---|
94
+ | `--json` | Output as JSON |
95
+ | `--dry-run` | Preview what would be upgraded without writing |
96
+
97
+ ```bash
98
+ brainclaw upgrade
99
+ brainclaw upgrade --dry-run
100
+ brainclaw upgrade --dry-run --json
101
+ ```
102
+
103
+ `upgrade` only covers store and generated-file migrations. On complex workspaces, it does not refresh machine detection, agent inventory, or brownfield bootstrap state by itself.
104
+
105
+ ### `brainclaw reconcile`
106
+
107
+ Refresh machine, agent, and bootstrap state after a package update or when onboarding an already-initialized multi-store workspace.
108
+
109
+ This is the command to use when `brainclaw upgrade` reports no schema migration, but the installed release still introduces new workspace-centric behavior that depends on:
110
+
111
+ - a refreshed `machine-profile`
112
+ - a refreshed `agent-inventory`
113
+ - refreshed bootstrap state for the current store and any nested Brainclaw stores discovered under a `multi-project` + `folder` workspace
114
+
115
+ | Option | Description |
116
+ |---|---|
117
+ | `--json` | Output as JSON |
118
+ | `--dry-run` | Preview the reconciliation plan without writing |
119
+ | `--apply-bootstrap` | Apply bootstrap suggestions across all selected stores after refresh |
120
+ | `-y, --yes` | Skip confirmation prompts for multi-store bootstrap apply |
121
+ | `--skip-machine-profile` | Skip machine profile refresh |
122
+ | `--skip-agent-inventory` | Skip agent inventory refresh |
123
+
124
+ ```bash
125
+ brainclaw reconcile --dry-run --json
126
+ brainclaw reconcile
127
+ brainclaw reconcile --apply-bootstrap -y
128
+ ```
129
+
130
+ Recommended post-update flow for an existing complex workspace:
131
+
132
+ ```bash
133
+ brainclaw upgrade --dry-run --json
134
+ brainclaw reconcile --dry-run --json
135
+ brainclaw reconcile --apply-bootstrap -y
136
+ brainclaw context --json
137
+ brainclaw doctor --json
138
+ ```
139
+
140
+ For a `multi-project` workspace using `projects.strategy: folder`, `reconcile` treats the current store as the workspace root and plans refreshes for nested child stores that already contain their own `.brainclaw/` directories.
141
+
63
142
  ### `brainclaw status`
64
143
 
65
144
  Show the current state of project memory.
@@ -75,6 +154,8 @@ brainclaw status --json
75
154
  brainclaw status --markdown
76
155
  ```
77
156
 
157
+ In `multi-project` mode, status now reports the effective project count resolved for the workspace. With `projects.strategy: folder`, that includes child stores discovered from nested `.brainclaw/` directories even when `config.projects.known` is still empty.
158
+
78
159
  ### `brainclaw doctor`
79
160
 
80
161
  Run health checks on config, state, and generated views.
@@ -94,6 +175,8 @@ brainclaw doctor --fix-agent-ignore
94
175
 
95
176
  When Brainclaw detects generated local agent files such as `.mcp.json` or `.claude/settings.local.json` inside a Git repo, `doctor` warns if they are not ignored or are still tracked. `--fix-agent-ignore` only updates `.gitignore`; if a file is already tracked you still need to untrack it with `git rm --cached <path>`.
96
177
 
178
+ In `multi-project` mode with `projects.strategy: folder`, `doctor` now checks the effective workspace project set, not just `config.projects.known`. That avoids false positives on workspaces that resolve child stores from the filesystem or global project registry.
179
+
97
180
  ### `brainclaw rebuild`
98
181
 
99
182
  Regenerate `project.md` from canonical state. No options.
@@ -133,7 +216,7 @@ brainclaw bootstrap --apply -y
133
216
 
134
217
  ### `brainclaw env`
135
218
 
136
- Display environment and tooling detection information.
219
+ Display environment, tooling detection, and installable Brainclaw update information.
137
220
 
138
221
  | Option | Description |
139
222
  |---|---|
@@ -146,6 +229,56 @@ brainclaw env --json
146
229
  brainclaw env --agent-tooling
147
230
  ```
148
231
 
232
+ When the project does not pin a local release channel, `brainclaw env` checks the public npm `latest` channel for installable updates. Projects can override that with `brainclaw_update_source`, for example to use `prelaunch` or a local-pack manifest.
233
+
234
+ ### `brainclaw surface-task <subcommand>`
235
+
236
+ Manage queued tasks for non-editing AI work surfaces such as `ChatGPT Desktop`, `Claude Desktop`, or `Gemini Web`.
237
+
238
+ This command is useful when the active coding agent should keep building in the repo, but another local AI surface would be a better fit for a related task such as:
239
+
240
+ - generating a visual asset
241
+ - drafting polished copy
242
+ - writing a release summary
243
+ - doing side research or structured analysis
244
+
245
+ Supported subcommands:
246
+
247
+ - `create`
248
+ - `list`
249
+ - `update`
250
+
251
+ | Option | Description |
252
+ |---|---|
253
+ | `--target <surface>` | Target surface such as `chatgpt`, `claude`, or `gemini` |
254
+ | `--kind <kind>` | `visual_asset`, `draft`, `summary`, `analysis`, `research`, or `custom` |
255
+ | `--instructions <text>` | Detailed task instructions |
256
+ | `--output <paths...>` | Expected output files or deliverables |
257
+ | `--tag <tags...>` | Optional tags |
258
+ | `--path <paths...>` | Related repo paths |
259
+ | `--status <status>` | For `list` filtering or `update`: `queued`, `in_progress`, `completed`, `cancelled`, `failed` |
260
+ | `--result <text>` | Result note when updating a task |
261
+ | `--all` | Include completed, cancelled, and failed tasks in `list` |
262
+ | `--json` | Output as JSON for `list` |
263
+
264
+ ```bash
265
+ brainclaw surface-task create "Generate homepage hero visual" \
266
+ --target chatgpt \
267
+ --kind visual_asset \
268
+ --instructions "Create a lightweight SaaS hero visual in PNG format." \
269
+ --output assets/hero-home.png \
270
+ --path src/pages/Home.tsx
271
+
272
+ brainclaw surface-task list
273
+
274
+ brainclaw surface-task update ast_12345678 \
275
+ --status completed \
276
+ --result "Saved the visual to assets/hero-home.png" \
277
+ --output assets/hero-home.png
278
+ ```
279
+
280
+ These tasks are local project coordination state. They do not execute automatically yet. The intended model is that Brainclaw can queue work for another local AI surface so that the next session on that surface can pick it up cleanly.
281
+
149
282
  ---
150
283
 
151
284
  ## Memory Management
@@ -1253,3 +1386,10 @@ brainclaw version
1253
1386
  brainclaw version --check
1254
1387
  brainclaw version --publish-local --release-notes "Add estimation-report command"
1255
1388
  ```
1389
+
1390
+ `brainclaw version --check` now follows this order:
1391
+
1392
+ - if `brainclaw_update_source` is configured, use it
1393
+ - otherwise, fall back to the public npm channel `brainclaw@latest`
1394
+
1395
+ This keeps end-user installs aware of published npm releases without requiring a local tarball channel. To keep beta testers on a different channel, set `brainclaw_update_source` to `type: npm` with a different `dist_tag`, such as `prelaunch`.
@@ -16,16 +16,19 @@ MCP matters because Brainclaw's value is mostly in dynamic state:
16
16
 
17
17
  Static files still help, but they age immediately. MCP is the stronger path for live coordination.
18
18
 
19
+ That now also includes Brainclaw's own install channel state: `bclaw_get_execution_context` surfaces whether a newer npm or local-pack build is available, so the agent can notice upgrades without relying on a human to run `brainclaw version --check`.
20
+
19
21
  ## Recommended Agent Pattern
20
22
 
21
23
  The default dynamic workflow is:
22
24
 
23
25
  1. `bclaw_session_start` to open work and get the current board/context
24
- 2. `bclaw_get_context` when the target path or task changes
25
- 3. `bclaw_list_plans` and `bclaw_list_claims` to inspect active work
26
- 4. `bclaw_claim` before editing
27
- 5. `bclaw_write_note` for runtime observations
28
- 6. `bclaw_session_end` to close cleanly and hand work off
26
+ 2. `bclaw_get_execution_context` early in the session when the agent needs local tooling signals or package update visibility
27
+ 3. `bclaw_get_context` when the target path or task changes
28
+ 4. `bclaw_list_plans` and `bclaw_list_claims` to inspect active work
29
+ 5. `bclaw_claim` before editing
30
+ 6. `bclaw_write_note` for runtime observations
31
+ 7. `bclaw_session_end` to close cleanly and hand work off
29
32
 
30
33
  This keeps session continuity inside Brainclaw instead of pushing the agent back to manual CLI usage.
31
34
 
@@ -35,7 +38,7 @@ This keeps session continuity inside Brainclaw instead of pushing the agent back
35
38
  |---|---|
36
39
  | `bclaw_get_context` | Ranked prompt-ready context, supports `digest: true` |
37
40
  | `bclaw_bootstrap` | Derive brownfield bootstrap signals, return adaptive interview prompts, accept structured interview answers, and preview/apply a selective import proposal |
38
- | `bclaw_get_execution_context` | Inspect local execution context and agent tooling |
41
+ | `bclaw_get_execution_context` | Inspect local execution context, installable update status, and agent tooling |
39
42
  | `bclaw_write_note` | Record a runtime note, supports `autoReflect: true` |
40
43
  | `bclaw_read_handoff` | Read active handoffs |
41
44
  | `bclaw_get_agent_board` | Coordination snapshot |
@@ -65,6 +68,8 @@ brainclaw mcp
65
68
 
66
69
  In practice, most agents pick this up through generated MCP config such as `.mcp.json`, `~/.cursor/mcp.json`, or other agent-specific config files written by `brainclaw setup`, `brainclaw init`, or `brainclaw export`.
67
70
 
71
+ By default, installable update checks use the public npm channel `brainclaw@latest`. Projects that need a different channel can override `brainclaw_update_source`, for example with `type: npm` and `dist_tag: prelaunch`, or with `type: local-pack` for local tarball workflows.
72
+
68
73
  ## Bootstrap Through MCP
69
74
 
70
75
  For agent-first onboarding, `bclaw_bootstrap` is the nominal path:
@@ -39,6 +39,7 @@ After the workspace is initialized, the nominal flow is:
39
39
 
40
40
  ```text
41
41
  bclaw_session_start -> open a session and return current board/context
42
+ bclaw_get_execution_context -> inspect local tooling and notice package updates
42
43
  bclaw_get_context -> fetch fresh prompt-ready context for the target path
43
44
  bclaw_list_plans -> inspect active work
44
45
  bclaw_claim -> claim scope before editing
@@ -48,6 +49,8 @@ bclaw_session_end -> close session cleanly and hand work off
48
49
 
49
50
  Use native agent files such as `AGENTS.md`, `CLAUDE.md`, or Cursor rules as local workflow guidance, not as the only source of live state.
50
51
 
52
+ Unless the project overrides `brainclaw_update_source`, `bclaw_get_execution_context` checks the public npm `latest` channel so the agent can notice when a newer Brainclaw release is available.
53
+
51
54
  ## Path 2: CLI-Oriented Agent Or Fallback Workflow
52
55
 
53
56
  Use this path when the agent does not have a good MCP integration yet, or when a human needs to drive the workflow directly.
@@ -84,6 +87,43 @@ brainclaw status
84
87
 
85
88
  Claims reduce collisions, but they are not a substitute for isolated worktrees yet. Use them mainly to coordinate sequential work or human/agent awareness in the same repo.
86
89
 
90
+ ## Path 2.5: Desktop AI Work Surfaces Around The Repo
91
+
92
+ Use this path when the active coding agent should stay focused on code, but the project could benefit from another local AI surface on the same machine, such as ChatGPT Desktop or Claude Desktop.
93
+
94
+ Typical use cases:
95
+
96
+ - visual asset generation
97
+ - polished copy or release-note drafting
98
+ - synthesis for operators or stakeholders
99
+ - side research that should not consume the coding agent's main context window
100
+
101
+ ### Discover what is available on the machine
102
+
103
+ ```bash
104
+ brainclaw machine-profile --refresh
105
+ ```
106
+
107
+ ### Queue work for another local AI surface
108
+
109
+ ```bash
110
+ brainclaw surface-task create "Generate homepage hero visual" \
111
+ --target chatgpt \
112
+ --kind visual_asset \
113
+ --instructions "Create a lightweight product hero visual for the landing page." \
114
+ --output assets/hero-home.png \
115
+ --path src/pages/Home.tsx
116
+ ```
117
+
118
+ ### Review queued work later
119
+
120
+ ```bash
121
+ brainclaw surface-task list
122
+ brainclaw surface-task list --all --target chatgpt
123
+ ```
124
+
125
+ This queue does not automate the target desktop app yet. It gives the project a clean place to stage work that another local AI surface should pick up during its next session.
126
+
87
127
  ## Path 3: Brownfield Onboarding
88
128
 
89
129
  Use this path when you are adopting Brainclaw into an existing workspace and do not want to hand-author all memory from scratch.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainclaw",
3
- "version": "0.19.11",
3
+ "version": "0.19.14",
4
4
  "description": "Shared project memory for humans and coding agents.",
5
5
  "type": "module",
6
6
  "bin": {