Skip to content

feat(mod): report compacting while Claude Code compacts the conversation - #57

Merged
omartelo merged 2 commits into
mainfrom
feat/session-lifecycle-states
Oct 9, 2026
Merged

omartelo merged 2 commits into
mainfrom
feat/session-lifecycle-states

Conversation

@omartelo

@omartelo omartelo commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Client side of the session-state contract's new compacting state (lichdotdev/lich#687).

What

hooks/mod-compacting.js (registered by hooks/lich.js) brackets session.compact:
compacting before the compaction runs, then the state the session returns to once
next(e) settles, whether it resolved or rejected. A manual /compact closes with
done, an automatic one with busy, because its turn is still running and the turn's
own Stop reports done. Only the manual and auto triggers are hooked, each through
its own matcher. A subagent's compaction (agentId) is passed through, and so is a
non-interactive run.

Measured (Claude Code 2.1.295, interactive PTY, stub lich)

  • session.compact: {trigger: "manual"|"auto", messages}. next(e) resolves to
    {messages} after the summary (manual ~6s, auto ~14s).
  • Esc on /compact makes next(e) reject with "Request was aborted". An auto
    compaction the engine gives up on rejects within ~40ms with "reactive compaction
    did not settle ok", and the turn continues. PostCompact fires in neither case,
    which is why this is a mod and not a settings hook.
  • Before this, a manual /compact left the card on done (no UserPromptSubmit),
    and an auto compaction showed a bare spinner.
  • Live run with this branch: manual gives compacting → done; auto gives
    busy → compacting → busy → done.

Discarded

  • session.end (reason): the existing SessionEnd → idle already covers /clear,
    /resume, /branch and exit. Claude Code awaits it before SessionStart, so idle
    always lands before the new /session-start id, and the card ends up right.
  • session.attach/detach: never fired in a PTY session. Tested with Remote
    Control opened from claude.ai. Only a stream-json ui_attach from a remote
    render surface raises it.

Notes for review

  • tests/lich-ref stays at v0.61.0. tests/refresh-fixtures.sh reads session-state.jsonl
    alone at f4481848, the commit where feat: show a Claude Code card's compaction as "Compacting..." lich#687 was merged into lich's main and
    which no release includes yet. Once a lich release includes that merge, move
    lich-ref to that release and put the file back in the loop.
  • Two assertions in tests/hooks.test.mjs pinned the old state vocabulary. They
    now expect compacting in the fixtures, and scripts are no longer expected to
    register it, since Claude Code reports it from the mod and no other harness
    reports it.
  • The release that carries this must be a minor (lich raised its plugin ceiling
    to 0.20.0). There is no version bump here.

node --test tests/*.test.mjs: 356/356. claude plugin validate .claude-plugin/plugin.json: passes; the warnings are the "gating hook without .catch" ones the other mods already have.

@omartelo
omartelo merged commit 021ad40 into main Oct 9, 2026
3 checks passed
@omartelo
omartelo deleted the feat/session-lifecycle-states branch October 9, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant