diff --git a/.ai/contexts/README.md b/.ai/contexts/README.md index fa2b48cc..d6b91f74 100644 --- a/.ai/contexts/README.md +++ b/.ai/contexts/README.md @@ -1,6 +1,8 @@ # Context engineering — Switchboard -Seven sub-system docs, ~150 lines each, written for AI agents who need to make a focused change without re-reading 1800 LOC of `main.js`. +Seven sub-system docs (76 to 526 lines as of 2026-09, most have grown well past +their original size), written for AI agents who need to make a focused change +without re-reading `main.js`, now ~2600 LOC. ## When to read which diff --git a/.ai/contexts/ipc-bridge.md b/.ai/contexts/ipc-bridge.md index ba90836e..bdc57b2f 100644 --- a/.ai/contexts/ipc-bridge.md +++ b/.ai/contexts/ipc-bridge.md @@ -8,8 +8,8 @@ This file is the **canonical inventory** of the IPC surface. When you add a new | File | LOC | Role | |---|---|---| -| `preload.js` | ~130 | The `contextBridge.exposeInMainWorld('api', {...})` block. Every renderer-facing function. | -| `main.js` | ~1850 | The `ipcMain.handle('', ...)` and `ipcMain.on('', ...)` handlers, scattered throughout. | +| `preload.js` | ~150 | The `contextBridge.exposeInMainWorld('api', {...})` block. Every renderer-facing function. | +| `main.js` | ~2600 | The `ipcMain.handle('', ...)` and `ipcMain.on('', ...)` handlers, scattered throughout. | ## Public surface (IPC inventory) @@ -155,7 +155,7 @@ session object exists. `cli-busy-state` is emitted **strictly on transitions** (`main.js` OSC 0 / OSC 9;4 handlers only send when `session._cliBusy` flips). A renderer that misses one — reload, mis-keyed id, a `session-forked` re-key — stays wrong forever, because no further event is coming. That is why `get-active-sessions` carries `busy`: `pollActiveSessions()` (3s while any PTY runs, 30s otherwise) hands the snapshot to `reconcileBusyState()` in `public/session-activity.js`, which realigns `sessionBusyState` and the sidebar classes. -> `session-detected` (tempId → realId) has a preload bridge and an `app.js` listener but **no emitter in main today** — `session-transitions.js:336` only sends `session-forked`. The `rekeyActivityState` call in `onSessionDetected` is therefore unreachable; it is kept so the handler stays correct if the channel comes back, not because it runs. +> `session-detected` (tempId → realId) has a preload bridge and an `app.js` listener but **no emitter in main today** — `session-transitions.js:427` only sends `session-forked`. The `rekeyActivityState` call in `onSessionDetected` is therefore unreachable; it is kept so the handler stays correct if the channel comes back, not because it runs. Three things make that safe: diff --git a/.ai/contexts/schedule-runner.md b/.ai/contexts/schedule-runner.md index e0a67d4c..e9a21002 100644 --- a/.ai/contexts/schedule-runner.md +++ b/.ai/contexts/schedule-runner.md @@ -6,7 +6,7 @@ | File | LOC | Role | |---|---|---| -| `schedule-runner.js` | ~220 | The cron loop, cron parser, file scanner, session pre-seeder, command builder. | +| `schedule-runner.js` | ~310 | The cron loop, cron parser, file scanner, session pre-seeder, command builder. | | `schedule-ipc.js` | ~220 | IPC handlers + the inline `SCHEDULE_CREATOR_TEMPLATE` (an embedded Claude command that teaches Claude how to write schedule files). | ## Public surface @@ -64,7 +64,7 @@ cli: - `public/memory-workfiles-view.js` brain tab — lists existing `schedule-*.md` files, surfaces the "run now" play button - `public/sidebar.js` — `.project-schedule-btn` clock icon wiring per project - `schedule-ipc.js` `SCHEDULE_CREATOR_TEMPLATE` — if you change the schedule file format, update the template's instructions -- `main.js:1618` (or wherever `startScheduler(log, runScheduleCommand)` is invoked at app boot) +- `main.js:2517` (or wherever `startScheduler(log, runScheduleCommand)` is invoked at app boot — checked 2026-09, it moves as main.js grows) - The `runScheduleCommand` factory in `main.js` — uses `child_process.spawn`, `cleanPtyEnv`, and the global shell profile. Schedules don't get their own shell selector. ## Limitations worth knowing diff --git a/.ai/contexts/session-cache.md b/.ai/contexts/session-cache.md index bac45bb2..03794422 100644 --- a/.ai/contexts/session-cache.md +++ b/.ai/contexts/session-cache.md @@ -6,11 +6,11 @@ | File | LOC | Role | |---|---|---| -| `db.js` | ~450 | SQLite (better-sqlite3) schema + prepared statements. Owns `session_cache`, `session_meta`, `cache_meta`, `settings`, `search_fts` (FTS5 + trigram tokenizer). | -| `session-cache.js` | ~525 | Indexer + watcher. Reads `~/.claude/projects//*.jsonl` (+ subagents subdir), populates rows, emits projects-changed events. | -| `read-session-file.js` | ~280 | Streaming JSONL reader. `readSessionFile()` (full) + `readSessionDisplayHeader()` (256 KB / 500 lines — cheap header for huge files). | -| `encode-project-path.js` | 14 | `/path/to/project` → `-path-to-project` folder name. Mirrors Claude CLI's encoding. | -| `derive-project-path.js` | 64 | Inverse: read `cwd` field from JSONL, derive original projectPath. **Collapses worktrees back to parent repo** via `resolveWorktreePath`. | +| `db.js` | ~895 | SQLite (better-sqlite3) schema + prepared statements. Owns `session_cache`, `session_meta`, `cache_meta`, `settings`, `search_fts` (FTS5 + trigram tokenizer). | +| `session-cache.js` | ~690 | Indexer + watcher. Reads `~/.claude/projects//*.jsonl` (+ subagents subdir), populates rows, emits projects-changed events. | +| `read-session-file.js` | ~420 | Streaming JSONL reader. `readSessionFile()` (full) + `readSessionDisplayHeader()` (256 KB / 500 lines — cheap header for huge files). | +| `encode-project-path.js` | 28 | `/path/to/project` → `-path-to-project` folder name. Mirrors Claude CLI's encoding. | +| `derive-project-path.js` | ~155 | Inverse: read `cwd` field from JSONL, derive original projectPath. **Collapses worktrees back to parent repo** via `resolveWorktreePath`. | ## Public surface diff --git a/.ai/contexts/subagent-observability.md b/.ai/contexts/subagent-observability.md index 135898e6..68fb0cae 100644 --- a/.ai/contexts/subagent-observability.md +++ b/.ai/contexts/subagent-observability.md @@ -88,7 +88,7 @@ This is the **#1 fork-specific feature** (upstream PR #47 still pending). It per `pruneStaleGridSubagents()` in `grid-view.js`, pruned from `wrapInGridCard()` rather than on a timer). Renderer files are plain non-module `