Skip to content

Commit db92b3a

Browse files
CLAUDE.md: correct the additionalContext 'threshold' — ~10KB inline, ~25KB+ wrapped-but-file-readable (not a 2KB hard cap)
Empirically tested: 9.8KB additionalContext reaches the model fully inline; 30KB/60KB get a 2KB preview + full content in a Read-able file. claude-mem uses the identical mechanism. The 2.68.0 'tools never learned' was a 24KB payload crossing the wrap threshold with tools buried last, not a 2KB truncation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 2052c8e commit db92b3a

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ Server → Client: `created`, `output`, `msg` (normalized: op=create/edit/meta),
889889
- Session status (2.31.0; sidebar surfacing 2.37.0): session-level `state` (working/needs-input/blocked/review) + `urgency` (low/normal/high/urgent) + reason. The AGENT sets its own via `vibespace-status` (spawn env: `VIBESPACE_API`, per-session `VIBESPACE_SESSION_TOKEN`, data/bin prepended to PATH); the user overrides/clears via the card chip popover. **SYNTHESIZED chip on EVERY live/tmux card (2.37.0)**: agent-declared state wins; else OSC-idle (`getWaitingSessionKeys`) ⇒ needs-input, else live ⇒ working — synthesized chips render dashed+dim (`.sess-state-derived`) vs solid for declared. **Urgency drives sidebar sort (2.37.0)**: `_sortSessions` ranks by `_sessionSortRank` (urgent>high>normal>low; blocked/needs-input/OSC-waiting also bump) BEFORE starred/recency; waiting keys cached per render pass (`_waitingSet`, cleared via queueMicrotask). Walter's task-centric fork (which inspired urgency-as-priority) isn't in this repo — this reuses our own state+urgency, which just wasn't wired to sort/always-shown before. Overriding an agent-set value records a pendingNotice → appended as `<system-reminder>` to the NEXT chat-input (ws-handler) so the agent calibrates (verified in a live transcript). Cards show a colored chip (+`!`/`!!` urgency, urgent pulses). KEY SPACES (do not regress): records key by `backend:backendSessionId`, or `webui:<serverId>` before the id exists — client reads try both, and `_sessionStatusKeyFor` WRITES to the key an existing record lives under (else user override lands on a second record and override detection silently misses); the agent route rekeys webui:→real on its next call
890890
- Hook install management (2.33.0): Manage Agents dialog (local machine) shows a "VibeSpace integration" row — per-harness hook status in plain language + Install/Reinstall (regenerates the script too) + Remove. Auto-registration at startup unchanged; the dialog is the non-engineer-visible surface for it.
891891
- vibespace-task CLI (2.33.0 local, 2.34.0 remote): agents report task-level updates — `progress "note"`, `plan-check <n|text>`, `plan-add`, `status <enum>`, `show` — scoped server-side to the session's context task; taught by the injected context rules. REMOTE (2.34.0): distributed to `~/.vibespace/bin` on the remote and reaches VIBESPACE_API through the ssh reverse tunnel — verified writing back from AIDev.
892-
- Anti-misconfiguration for the agent tools (2.37.0): both `vibespace-task` and `vibespace-status` print usage AND the current state on NO args, list valid subcommands on an unknown one, and validate their enum locally. NOTE (superseded by 2.39.0): `vibespace-task status` no longer exists — a Task Group has no status; a session reports its own state via `vibespace-status <working|needs-input|blocked|review|done>`. `renderContext`'s "How to report back" was rewritten: `vibespace-task` commands are scoped to the session's live Task-Group belonging via the `vsst_` token (with >1 group the agent passes `--group`, validated to be one it belongs to — there is no `session._taskId` anymore), and "run bare to self-check" is the fallback. **Injection ORDER + SIZE are load-bearing (2.68.0, real incident):** Claude Code PERSISTS an oversized hook additionalContext to disk and hands the agent only a ~2KB HEAD preview — the old layout (24KB Activity log first, tool rules last) meant agents saw a pure-log preview and NEVER learned the vibespace tools (observed fleet-wide non-usage). renderContext now orders identity/objective/checklist → HOW TO REPORT BACK → context folder → Activity log LAST, with the log BYTE-BUDGETED (total ≤ ~8KB, newest entries win, ≥3 ≤12, "last N of M" pointer; renderMultiContext splits the budget across groups). TASK.md keeps 50 entries.
892+
- Anti-misconfiguration for the agent tools (2.37.0): both `vibespace-task` and `vibespace-status` print usage AND the current state on NO args, list valid subcommands on an unknown one, and validate their enum locally. NOTE (superseded by 2.39.0): `vibespace-task status` no longer exists — a Task Group has no status; a session reports its own state via `vibespace-status <working|needs-input|blocked|review|done>`. `renderContext`'s "How to report back" was rewritten: `vibespace-task` commands are scoped to the session's live Task-Group belonging via the `vsst_` token (with >1 group the agent passes `--group`, validated to be one it belongs to — there is no `session._taskId` anymore), and "run bare to self-check" is the fallback. **Injection ORDER + SIZE are load-bearing (2.68.0, real incident; THRESHOLD corrected 2026-07-13 by empirical test):** hook additionalContext up to ~10KB reaches the model FULLY INLINE (verified: a 9.8KB block's end-marker was seen). Only ABOVE ~25KB does Claude Code wrap it in `<persisted-output>` — a ~2KB inline preview PLUS the full content saved to a file the agent can Read (verified at 30KB/60KB). So there is NO 2KB hard cap (the old note misread this); the 2.68.0 failure was a 24KB Activity-log-FIRST payload crossing the wrap threshold → agents got a useless log preview + never Read the file for the tools. claude-mem uses the IDENTICAL additionalContext mechanism — no magic. Keep injections tight anyway (tools-first, byte-budgeted ~8KB) so everything stays inline — the old layout (24KB Activity log first, tool rules last) meant agents saw a pure-log preview and NEVER learned the vibespace tools (observed fleet-wide non-usage). renderContext now orders identity/objective/checklist → HOW TO REPORT BACK → context folder → Activity log LAST, with the log BYTE-BUDGETED (total ≤ ~8KB, newest entries win, ≥3 ≤12, "last N of M" pointer; renderMultiContext splits the budget across groups). TASK.md keeps 50 entries.
893893
- Repo task files (2.34.0, P4): a task ⇄ a committable markdown file. Task detail window "Repo file" → Export (frontmatter id/title/kind/status/color + objective + plan + progress); board "Import…" card reads such a file back into the store (frontmatter authoritative; existing sessions/folders/progress preserved). Server `TaskManager.exportToFile/importFromFile` + `/api/tasks/:id/export|import`. The store stays authoritative — the file is a projection/seed, never live-parsed.
894894
- Task context injection (2.34.0, P2 — hook-ONLY, NEVER message injection): the user's message text is sent VERBATIM; task context + status-override notices ride the harness's OWN native hooks via `data/bin/vibespace-hook.mjs` (registered for BOTH `SessionStart` and `UserPromptSubmit`). Rewriting the user's input to smuggle context (the earlier codex/remote "first message" approach) was RIPPED OUT — it bypasses the CLI and is unstable (user directive 2026-07-05). Hook output MUST be ONLY the nested `{hookSpecificOutput:{hookEventName, additionalContext}}` shape — an extra top-level `additionalContext` key makes CODEX reject the whole object (its `*HookSpecificOutputWire` schema is `additionalProperties:false`); Claude is lenient but reads the same nested field (2.1.201 binary hints "Did you mean hookSpecificOutput"). **`/api/agent/task-context`** (SessionStart) delivers context, sets `_taskCtxDelivered` (gated `backend!=='codex'`); **`/api/agent/prompt-context`** (UserPromptSubmit) delivers context on the FIRST prompt when SessionStart didn't (codex path) + any pending status-override notice (consumed once). **Per-turn micro-reminder (2.78.0, user request):** when NOTHING bigger is delivered on a prompt, the route returns a ~330-byte `<vibespace-reminder>` one-liner (status/ask/task, `--group <id>` variant for multi-group) so tools stay in the agent's working context on long sessions — the start-of-session rules scroll out and usage decays. Gated by `agents.perTurnToolReminder` (default ON, liveApply); claude gets it via the UserPromptSubmit hook, codex via the wrapper's per-turn inject. BACKEND REALITY (verified live with a codeword-in-objective): **Claude fires + INJECTS both hooks** (terminal + chat, local + remote) — fully works via hooks. **Codex app-server RUNS hook commands but does NOT inject their `additionalContext`** in JSON-RPC mode (0.142.5) — so for CODEX the hook is NOT the delivery path. Instead (2.35.0, research-verified) the **codex-chat-wrapper injects context natively via `thread/inject_items`** (a first-class app-server method that appends a `role:'developer'` message to the thread's model-visible history out-of-band from the user turn): `injectTaskContextForTurn()` calls `/api/agent/prompt-context` before each `turn/start` and, if non-empty, injects it. Verified: codex answered a codeword only in the task objective, AND the NEW codeword after an edit. GOTCHA that cost a debug cycle: the VIBESPACE_* env reached the spawned CLI (argv `env VAR=val` prefix) but NOT the WRAPPER's own process.env, so the wrapper's inject silently no-op'd — the wrapper (always LOCAL, even for remote sessions) now gets VIBESPACE_API=127.0.0.1:<PORT> + token + task id in the dtach process env directly. The `vibespace-hook.mjs` UserPromptSubmit hook stays registered (works for Claude; harmless for codex). **Task-update injection (2.35.0; DIFF-BASED since 2.113.0):** both endpoints track per-session `_groupSeenAt` (the `contentUpdatedAt` last delivered) — so any group change (UI or another session's vibespace-task) reaches the agent on its NEXT turn, no per-turn noise otherwise. Since 2.113.0 an UPDATE delivers only the DELTA, not the full re-render: every delivery also snapshots the group (`s._groupSnap` via tasks.snapshotForDiff) and later changes inject a `<vibespace-task-update>` block from tasks.renderContextDiff (checklist added/checked/unchecked/removed, objective/title edits, changed contextDir files, new activity entries — see the agent-routes.js file-structure note for the full contract; toggle `agents.contextUpdateDiffs`). Claude gets it via the UserPromptSubmit hook; codex via the wrapper's per-turn inject. TASK.md: TaskManager writes `<contextDir>/.vibespace/TASK.md` on every change + boot (program-only writer, content-compare guard, atomic). Remote (P3): the ssh spawn opens a reverse tunnel `-R <rport>:127.0.0.1:<PORT>` (remote agent tools/hook reach VIBESPACE_API through it) and the prelude base64-distributes the 4 tools to `~/.vibespace/bin` on the remote + runs `vibespace-hook-register.mjs` to register the hook in the REMOTE's own settings (its local Claude/Codex fires the hook, not ours) — verified end-to-end on AIDev (remote claude answered the codeword; remote `vibespace-task progress` wrote back through the tunnel)
895895
- New session from a task (2.31.0): the New Session dialog has a Task dropdown (None + all tasks; picking one prefills cwd from folders[0] if empty). Task board + button / context menu open the dialog PRE-FILLED (task selected, cwd = first auto-include folder) — user confirms params. Chosen task → `taskId` in the ws create → `session._initialGroupId` (covers the pre-bind window; there is NO `VIBESPACE_TASK_ID` env anymore — belonging is resolved live from the `vsst_` token per 2.39.0) + client binds the session via `_pendingTaskBinds` once the backend id appears in active-sessions (folder-less groups need the explicit tag; reload before id adoption loses the pending bind — acceptable). (2.54.0) With a group selected, the cwd quick-fill CHIPS pin the group's folders first (`_taskCwdSuggestions` → `.cwd-task-chip` with the group color dot; re-rendered on Task-dropdown change) — and recursive folders also suggest nested session cwds (strict `path+'/'` prefix on cwd|realCwd, local sessions only, sorted by session count); the autocomplete priorityPaths float is separate and unchanged

0 commit comments

Comments
 (0)