Skip to content

feat(enable): show progress while importing existing sessions - #1848

Open
ecgang wants to merge 3 commits into
entireio:mainfrom
ecgang:eric/staqpro-771-enable-import-progress
Open

feat(enable): show progress while importing existing sessions#1848
ecgang wants to merge 3 commits into
entireio:mainfrom
ecgang:eric/staqpro-771-enable-import-progress

Conversation

@ecgang

@ecgang ecgang commented Jul 24, 2026

Copy link
Copy Markdown

Closes #1847.

First-run entire enable imports existing agent sessions with zero output between the setup summary and the final Imported N turn(s) line — on a large corpus that's an hour of bare cursor with no way to tell working from hung. This wires live progress into that import, following the CLI's existing startSpinner conventions.

before after
before: silent import after: live progress

Honesty note on the demo: both gifs use a synthetic fixture (6 sessions × 60 turns, ~15s import) so the behavior is visible in a short recording; the real-world case that motivated this was ~1h of silence.

What changed

  • agentimport: optional, UI-agnostic Progress reporter on OptionsSessionStart fires per session after turn-splitting; exactly one of TurnWritten / TurnSkipped fires per turn (skips cover already-imported turns and --dry-run), so callbacks always sum to turnCount. Nil reporter is byte-identical to before. No printing or logging inside the package.
  • startUpdatableSpinner — the smallest variant of the existing spinner whose message can change while it runs; startSpinner now delegates to it. Same glyphs, tick rate, 250 ms initial-draw delay, and TTY gating. One deliberate change: animated frames draw \r\033[K instead of bare \r, so a shrinking message can't leave stale trailing characters (final stop lines are byte-identical).
  • One shared wiring helper (newImportProgressReporter) used by both import surfaces — the entire enable first-run import and the standalone entire import <agent>:
    • interactive TTY: Importing Claude Code sessions... (session i/N · turn j/M) updating live
    • non-TTY / piped / ACCESSIBLE=1: one plain ANSI-free line per session (Importing Claude Code session i/N (M turns)...), keeping output complete for agents and screen readers per the repo's agent-safe CLI fallback guidance
  • The final Imported N turn(s) from M session(s) summary line is unchanged, and the spinner is stopped before any error path prints.

Tests

  • agentimport: callback contract (counts, ordering, exact tuples), nil-reporter equivalence, skipped-turn and dry-run invariants (written + skipped == turnCount).
  • cli: non-TTY progress lines (one per session, zero ESC bytes, unchanged summary line), spinner-variant behavior (fallback line, update-before-first-draw, stop semantics).
  • Full mise run check (fmt, lint, unit + integration + Vogon canary) green; also manually verified against a real built binary: piped output, ACCESSIBLE=1 under a PTY, and live-TTY spinner animation.

Happy to adjust the message format or UX approach if maintainers prefer something different.

🤖 Generated with Claude Code

ecgang and others added 3 commits July 23, 2026 20:35
Run previously gave callers no visibility into a potentially long
import (sessions x turns with a documented O(turns^2) recompute), so
first-run 'entire enable' sat silent for its whole duration. Add an
optional, UI-agnostic Progress struct on Options: SessionStart fires
per session after turn splitting, TurnWritten after each turn actually
written (never for skips or dry runs). Nil stays byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 01KY93365A3ZBK69V2948N4V4W
First-run 'entire enable' could sit silent for the whole session
import (an hour on a large corpus) between the setup summary and the
final Imported line. Wire the agentimport Progress reporter into
user-visible output via one shared helper:

- interactive terminals get the standard spinner, extended with an
  updatable message (startUpdatableSpinner; startSpinner now delegates
  to it) tracking 'session i/N - turn j/M' live
- non-TTY and ACCESSIBLE runs get one plain ANSI-free line per session,
  keeping output complete for agents and screen readers
- the standalone 'entire import <agent>' command gets the same wiring

The final summary line is unchanged, and the spinner stops before any
error path prints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 01KY93WZV7TJ0P4CSY40NYGZ1Q
The progress counter only advanced on TurnWritten, so a fully
idempotent re-import or a --dry-run pass sat at 'turn 0/M' and then
rendered that stale count into the completion line. Add
Progress.TurnSkipped, fired for every turn Run processes without
writing (already imported, or DryRun), and drive the UI counter from
both callbacks: exactly one of TurnWritten/TurnSkipped now fires per
turn, so the counter always sweeps to M/M truthfully.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 01KY95QCD5YDCST7YNYKW063FA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

entire enable: no progress indicator while importing existing sessions (can look hung for an hour)

1 participant