Skip to content

feat: restore previous sessions on startup - #333

Merged
kbwo merged 1 commit into
mainfrom
feat/restore-session
Sep 5, 2026
Merged

feat: restore previous sessions on startup#333
kbwo merged 1 commit into
mainfrom
feat/restore-session

Conversation

@kbwo

@kbwo kbwo commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Why

Quitting CCManager kills the assistant processes it started, so the next run opens on an empty menu and every session has to be found and started again by hand. This adds a startup offer to launch them again.

Restoring here means running each session's launch command in its worktree again — the previous terminal output and the conversation held inside the assistant are deliberately not brought back. Reproducing those was considered and dropped: it would mean owning a transcript format per assistant, and every assistant already has its own resume story.

How

A record of the sessions CCManager currently has open is kept in ~/.config/ccmanager/sessions.json. It is written as sessions come and go, not on exit, so a crash, a kill -9, or a closed terminal leaves it intact. Only what is needed to launch the same command again is stored (worktree, command preset id, session name, devcontainer commands, owning pid).

  • sessionRestoreStore — the record itself. Each mutation re-reads the file before rewriting it, so two CCManager processes sharing the file do not discard each other's sessions; writes go to a temp file and are renamed into place, so an interrupted write cannot truncate it. A corrupt or hand-edited file is ignored rather than fatal.
  • globalSessionOrchestrator — keeps the record in step with the live sessions. It is the only place that knows which project a session manager belongs to, so the wiring lives there instead of inside SessionManager. A session the user killed, or whose command exited on its own, is forgotten. The teardown on quit suspends tracking first — otherwise the shutdown would erase exactly the sessions the next run should offer.
  • sessionRestorer — narrows the record to what this run may offer (worktree still exists, owner process no longer running, matching project) and relaunches each entry. Sessions are started one at a time because each is numbered relative to the sessions already in its worktree. An initial prompt is not replayed.
  • RestoreSessions + App — the startup confirmation. Declining forgets the listed sessions so the offer does not return on the next start. Single-project mode offers only the repository being opened; multi-project mode offers every recorded project at once.

Supporting changes: Session now carries the preset id it was launched with, and renaming goes through SessionManager.renameSession so the record can follow the new name. Two blocks that were about to gain a third copy are extracted instead — the config directory path (utils/configDir) and the error message formatter (utils/errorMessage).

User-facing behaviour and the file location are documented in the README section added here.

Screens

The offer shown at startup when the last run left sessions open:

Restore previous sessions

Found 2 sessions from the last time ccmanager ran. Start them again?

  feature-login — Main
  fix-timeout (review) — Codex

> Restore
  Don't restore

Verification

  • bun run typecheck and bun run lint are clean.
  • bun run test: 1889 passing. New coverage: the record store (9), the restorer's filtering and relaunch paths (13), the orchestrator wiring including "keeps records on quit" (5), and the App startup flow (4).
  • Smoke-tested against a real PTY and a real SessionManager: creating a session writes a record, killing it removes the record, and the quit-time teardown leaves it in place.

Reviewers on macOS may see the three *.submodule.test.ts suites fail locally; they call git config --global in beforeAll and fail if that write is not permitted. They pass in a normal shell and are unrelated to this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LhdLZV7mP84ZzcK81HWzVU

Quitting ccmanager kills the assistant processes it started, so the next
run began with an empty menu and every session had to be reopened by
hand. This adds a startup offer to launch them again.

A durable record of the currently open sessions is written to
~/.config/ccmanager/sessions.json as sessions come and go, rather than on
exit, so a crash or a kill -9 leaves it intact. Only what is needed to
launch the same command again is recorded (worktree, command preset id,
session name, devcontainer commands); terminal output and the
conversation inside the assistant are deliberately not restored.

- sessionRestoreStore: the record itself. Each mutation re-reads the file
  before rewriting it so two ccmanager processes sharing the file do not
  discard each other's sessions, and writes go through a temp file plus
  rename so an interrupted write cannot truncate it.
- globalSessionOrchestrator: keeps the record in step with the sessions,
  since it is the only place that knows which project a session manager
  belongs to. A killed or self-exited session is forgotten; the teardown
  on quit suspends tracking first, so those sessions stay restorable.
- sessionRestorer: filters the record down to what this run may offer
  (worktree still present, owner process gone, matching project) and
  relaunches each one, one at a time so session numbering stays correct.
- RestoreSessions/App: the startup confirmation. Declining forgets the
  listed sessions so the offer does not come back. Single-project mode
  offers the repository being opened; multi-project mode offers every
  recorded project at once.

Session now carries the preset id it was launched with, and renaming goes
through SessionManager.renameSession so the record can follow it.

Also extracts two blocks that would otherwise have gained a third copy:
the ccmanager config directory path (utils/configDir) and the error
message formatter (utils/errorMessage).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhdLZV7mP84ZzcK81HWzVU
@kbwo
kbwo marked this pull request as ready for review September 5, 2026 04:59
@kbwo
kbwo merged commit 6328099 into main Sep 5, 2026
1 check passed
@kbwo
kbwo deleted the feat/restore-session branch September 5, 2026 04:59
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