Claudeclaw add-compact
Add /compact command for manual context compaction. Solves context rot in long sessions by forwarding the SDK's built-in /compact slash command. Main-group or trusted sender only.
install
source · Clone the upstream repo
git clone https://github.com/sbusso/claudeclaw
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/sbusso/claudeclaw "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/add-compact" ~/.claude/skills/sbusso-claudeclaw-add-compact && rm -rf "$T"
manifest:
skills/add-compact/SKILL.mdsource content
Add /compact Command
Adds a
/compact session command that compacts conversation history to fight context rot in long-running sessions. Uses the Claude Agent SDK's built-in /compact slash command — no synthetic system prompts.
Session contract:
/compact keeps the same logical session alive. The SDK returns a new session ID after compaction (via the init system message), which the agent-runner forwards to the orchestrator as newSessionId. No destructive reset occurs — the agent retains summarized context.
Phase 1: Pre-flight
Check if
src/session-commands.ts exists:
test -f src/session-commands.ts && echo "Already applied" || echo "Not applied"
If already applied, skip to Phase 3 (Verify).
Phase 2: Apply Code Changes
Merge the skill branch:
git fetch upstream skill/compact git merge upstream/skill/compact
Note:
is the remote pointing toupstream. If using a different remote name, substitute accordingly.sbusso/claudeclaw
This adds:
(extract and authorize session commands)src/session-commands.ts
(unit tests for command parsing and auth)src/session-commands.test.ts- Session command interception in
(bothsrc/index.ts
andprocessGroupMessages
)startMessageLoop - Slash command handling in
agent/runner/src/index.ts
Validate
npm test npm run build
Rebuild container
./src/runtimes/docker/build.sh
Service name: Derived from the directory name:
(macOS) /com.claudeclaw.<dirname>(Linux). For example, if cwd isclaudeclaw-<dirname>, the service ismy-assistant. Determine the correct service name before running service commands below.com.claudeclaw.my-assistant
Restart service
launchctl kickstart -k gui/$(id -u)/com.claudeclaw # macOS # Linux: systemctl --user restart claudeclaw
Phase 3: Verify
Integration Test
- Start ClaudeClaw in dev mode:
npm run dev - From the main group (self-chat), send exactly:
/compact - Verify:
- The agent acknowledges compaction (e.g., "Conversation compacted.")
- The session continues — send a follow-up message and verify the agent responds coherently
- A conversation archive is written to
(by the PreCompact hook)groups/{folder}/conversations/ - Container logs show
(confirms SDK actually compacted)Compact boundary observed - If
was NOT observed, the response says "compact_boundary was not observed"compact_boundary
- From a non-main group as a non-admin user, send:
@<assistant> /compact - Verify:
- The bot responds with "Session commands require admin access."
- No compaction occurs, no container is spawned for the command
- From a non-main group as the admin (device owner /
), send:is_from_me@<assistant> /compact - Verify:
- Compaction proceeds normally (same behavior as main group)
- While an active container is running for the main group, send
/compact - Verify:
- The active container is signaled to close (authorized senders only — untrusted senders cannot kill in-flight work)
- Compaction proceeds via a new container once the active one exits
- The command is not dropped (no cursor race)
- Send a normal message, then
, then another normal message in quick succession (same polling batch):/compact - Verify:
- Pre-compact messages are sent to the agent first (check container logs for two
calls)runAgent - Compaction proceeds after pre-compact messages are processed
- Messages after
in the batch are preserved (cursor advances to/compact
's timestamp only) and processed on the next poll cycle/compact
- Pre-compact messages are sent to the agent first (check container logs for two
- From a non-main group as a non-admin user, send
:@<assistant> /compact - Verify:
- Denial message is sent ("Session commands require admin access.")
- The
is consumed (cursor advanced) — it does NOT replay on future polls/compact - Other messages in the same batch are also consumed (cursor is a high-water mark — this is an accepted tradeoff for the narrow edge case of denied
+ other messages in the same polling interval)/compact - No container is killed or interrupted
- From a non-main group (with
enabled) as a non-admin user, send barerequiresTrigger
(no trigger prefix):/compact - Verify:
- No denial message is sent (trigger policy prevents untrusted bot responses)
- The
is consumed silently/compact - Note: in groups where
isrequiresTrigger
, a denial message IS sent because the sender is considered reachablefalse
- After compaction, verify no auto-compaction behavior — only manual
triggers it/compact
Validation on Fresh Clone
git clone <your-fork> /tmp/claudeclaw-test cd /tmp/claudeclaw-test claude # then run /add-compact npm run build npm test ./src/runtimes/docker/build.sh # Manual: send /compact from main group, verify compaction + continuation # Manual: send @<assistant> /compact from non-main as non-admin, verify denial # Manual: send @<assistant> /compact from non-main as admin, verify allowed # Manual: verify no auto-compaction behavior
Security Constraints
- Main-group or trusted/admin sender only. The main group is the user's private self-chat and is trusted (see
). Non-main groups are untrusted — a careless or malicious user could wipe the agent's short-term memory. However, the device owner (docs/SECURITY.md
) is always trusted and can compact from any group.is_from_me - No auto-compaction. This skill implements manual compaction only. Automatic threshold-based compaction is a separate concern and should be a separate skill.
- No config file. ClaudeClaw's philosophy is customization through code changes, not configuration sprawl.
- Transcript archived before compaction. The existing
hook in the agent-runner archives the full transcript toPreCompact
before the SDK compacts it.conversations/ - Session continues after compaction. This is not a destructive reset. The conversation continues with summarized context.
What This Does NOT Do
- No automatic compaction threshold (add separately if desired)
- No
command (separate skill, separate semantics —/clear
is a destructive reset)/clear - No cross-group compaction (each group's session is isolated)
- No changes to the container image, Dockerfile, or build script
Troubleshooting
- "Session commands require admin access": Only the device owner (
) or main-group senders can useis_from_me
. Other users are denied./compact - No compact_boundary in logs: The SDK may not emit this event in all versions. Check the agent-runner logs for the warning message. Compaction may still have succeeded.
- Pre-compact failure: If messages before
fail to process, the error message says "Failed to process messages before /compact." The cursor advances past sent output to prevent duplicates;/compact
remains pending for the next attempt./compact