feat(enable): offer to import agent history on first-time enable#1595
Conversation
First-time `entire enable` now offers to import pre-existing agent history for the agents selected during setup. Interactive runs show an unchecked multi-select of eligible agents — those with a registered importer and at least one discoverable session in the 30-day lookback window. Non-interactive runs (--yes or no TTY) auto-import all eligible agents. The offer is gated to first run via IsSetUpAny and is best-effort: discovery or import failures are logged and surfaced as a notice but never fail enable. Wired into both first-run enable paths — runEnableInteractive (bare / --yes) and setupAgentHooksNonInteractive (--agent) — reusing the same redaction + agentimport.Run flow as the standalone `entire import`. Entire-Checkpoint: 938f78effaff
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 885859c. Configure here.
There was a problem hiding this comment.
Pull request overview
This PR enhances the first-time entire enable experience by offering (or auto-running, in non-interactive mode) an import of pre-existing local agent session history for the agents selected during setup, reusing the existing entire import <agent> pipeline.
Changes:
- Capture a “first-run” gate in both enable paths and invoke a new
maybeOfferSessionImportflow afterstrategy.EnsureSetup. - Add
setup_import.goorchestration to discover eligible agents (byAgentType), optionally prompt via an accessible multi-select, and run imports best-effort. - Add unit + integration tests covering first-run gating, interactive selection, non-interactive auto-import, and re-enable no-op behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| cmd/entire/cli/setup.go | Captures firstRun before settings writes and calls maybeOfferSessionImport from both enable flows. |
| cmd/entire/cli/setup_import.go | Implements first-run session import offer/auto-import logic and reuse of agentimport.Run. |
| cmd/entire/cli/setup_import_test.go | Adds unit tests for gating, selection behavior, and importer matching. |
| cmd/entire/cli/integration_test/enable_import_test.go | Adds integration coverage for first-run import, no-history no-op, and re-enable not re-offering import. |
Address PR review feedback: - Thread ctx into promptImportSelection and use form.RunWithContext so parent-command cancellation stops the prompt and is handled by handleFormCancellation. - Never fail enable on a prompt/UI error: maybeOfferSessionImport is now void; prompt failures are logged, surfaced as a note, and skipped. - Fix stale doc comment referring to the old claudeFixture name. Entire-Checkpoint: e83ecb55af58
"Set up everything" used to dead-end at 3/4 with a run-later hint, because the import rung deliberately had no offer (deferred to the richer enable-time offer in PR #1595). Live testing showed that dead-end undercuts the flow: enable walks you through login and then stops one step short of done. Wire a minimal import offer — same flow as `entire import <agent>` (checkpoint policy honored, redaction config loaded, agentimport.Run per discoverable agent) — so the ladder carries through to Connected in one pass. When #1595 lands, its offer (per-agent selection, first-run gating) replaces these internals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 11dc95701f15
Correctness (the overclaiming-degradation cluster):
- A suspended mirror placement returns nil error from createAndAwaitMirror;
the offer now reports it like `repo mirror create` does, returns an error
so the rung keeps its retry hint, and skips the cache write-through that
claimed "mirrored" for the TTL (finalizeMirrorOffer, unit-tested).
- Import-scan failures no longer collapse into "no prior history found" or
a false Done: discovery errors poison the memo and count; all-agents-
failed returns an error so the rung renders Unknown with a retry hint.
- authRung distinguishes a keyring/token-store failure (Unknown + `entire
auth status`) from a genuinely empty token (Missing) — no more browser
logins offered against a broken keyring.
- mirrorRung maps origin-resolution failures to Unknown; only a non-GitHub
forge is NotApplicable ("no GitHub origin" was masquerading as fact).
- Explicit `entire enable` clears cached probe failures first — a transient
blip no longer suppresses the mirror offer for the failure TTL.
- offerable() gates Blocked rungs on an offerable blocker preceding them:
the consent prompt can no longer promise work that cannot run.
- `enable --agent` honors its documented non-interactive contract: the
ladder always runs with prompting suppressed there.
- patchSucceededOffers deleted: dead for mirror in production (the cache
write-through covers it) and it mislabeled auth/import failures as
"created — sync in progress".
Hardening and hygiene:
- setupModeSkip is now the mode enum's zero value (a forgotten mode must
never run login or mirror creation).
- Operational logging (logging.Warn/Debug) at every degrade-and-continue
point — discovery/dry-run/keyring/origin/prompt/offer failures now leave
a trace for doctor logs; no user content logged.
- Shared jsonFileCache shell with atomic tmp+rename writes replaces both
caches' hand-rolled non-atomic persistence.
- githubSlug() is the single encoding of the lowercase-slug invariant
(replaces the parseGitHubURL round-trip and inline ToLower calls).
- Dead Rung.Offer field removed; five rotted comments fixed (import-offer
enumeration, summary example, ground-truth qualifier, seam docs, #1595
prediction softened to a constraint).
- onboardingSetupSummary reuses formatTokenClassList.
- New tests: consent-cancel behaves like skip, step-by-step accept runs the
offer, blocked-gating, first-run and --agent call sites, suspended/empty
mirror outcomes, clearUnreachable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 732b4eb2ebf3
When only one agent is discoverable, the multi-select's "space to select, select none to skip" wording is confusing since there is nothing to choose between. Show a plain Import/Skip confirmation in that case instead; the multi-select is retained when multiple agents are eligible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Entire-Checkpoint: 01KWW3KDRZ8DPKM1H8395SKWKJ
… non-interactively
Two fixes from PR review:
- Validate the checkpoint policy before importing agent history, matching
the standalone `entire import` command's
ensureCheckpointPolicyAllowsCheckpointData check. Best-effort: an
unsupported/unreadable policy skips the import (logged + noted) rather
than failing enable.
- Only auto-import all eligible agents under an explicit --yes ("accept
all defaults"). A non-interactive enable without --yes (script, pipe,
or an agent with no TTY) no longer silently imports history; it points
at `entire import` instead.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entire-Checkpoint: 01KWWDN6KCZAM8GGPP06D8A1HD
…ve behavior The offer no longer auto-imports in a non-interactive enable without --yes. Update the integration tests accordingly: - FirstRunAutoImports now passes --yes to exercise auto-import. - Add NonInteractiveWithoutYesHints: a no-TTY enable without --yes must not import and must point at `entire import`. - NotOfferedOnReEnable passes --yes so the first enable imports. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Entire-Checkpoint: 01KWWH7M069H3SETEESW3DVBE8
… ladder PR #1595 merged on main with maybeOfferSessionImport called at the same insertion points as the ladder — the merge was textually clean but both import offers fired back-to-back on first-run enable. The ladder is now the single offer surface: - maybeOfferSessionImport and its first-run gate are gone; #1595's machinery (agent-scoped discovery, the per-agent picker, the policy-gated redaction- aware import runner) survives as the import rung's offer. - "Set up everything" imports all eligible agents (consent already given); step-by-step shows #1595's picker — Import/Skip for one agent, multi-select for several — as the rung's own confirmation, so the runner skips the generic yes/no for self-prompting offers. - --yes keeps #1595's contract (auto-imports; the merged integration tests assert it) via an autoRun mechanism scoped to the local-only import rung — login and mirror stay strictly opt-in. --agent still never prompts, and without --yes never auto-imports. - "No re-import on re-enable" now derives from ground truth (all history imported => rung Done) instead of a persisted first-run gate, so it composes with the resume path instead of fighting it. - #1595's orchestration unit tests are rewritten against the new entry point over the same seams; new runner tests cover autoRun and self-prompting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KWXZRCYHYMEGP8MNGYH9B7CZ
…sult Eight confirmed findings from the workflow review of the post-#1595 state: - Bootstrap enables (--init-repo / non-git dir) returned before the ladder, losing the import/login/mirror offers main used to give them. The ladder now runs before the SuppressDoneMessage early-return on both paths. - --yes auto-import is gated to the very first enable (firstRun captured before any settings write): ground truth cannot distinguish new history from history the user explicitly declined, so a later `enable --yes` must not import it. Restores #1595's exact --yes contract; interactive re-enables still offer, where consent is explicit. - Offer scope and rung scope now agree: the rung's Missing computation iterates agents with hooks installed (not every registered importer), so the checklist never promises an import the offer won't perform; the --agent and interactive paths thread their agent scope into the offer, so `enable --agent X --yes` no longer imports other agents' history. - The import rung honors the checkpoint policy: a policy-restricted repo renders "imports restricted by checkpoint policy" (NotApplicable) instead of Missing-forever with a consented no-op offer. - A failed rung confirm (Ctrl-C) stops the offer walk instead of surfacing every remaining prompt one abort at a time. - The mirror probe-cache write-through moved into createAndAwaitMirror, so the checklist's own hinted command (`entire repo mirror create <slug>`) and the wizard heal the cache too — a cached "not mirrored" no longer survives the prescribed remediation. finalizeMirrorOffer keeps only the suspended-placement handling. - runEnableOnboarding takes an options struct (assumeYes/neverPrompt/ firstRun/importScope); newEnableOnboardingRunner makes the option→runner mapping unit-testable. Deliberate behavior note: `enable --agent` on a TTY no longer shows the interactive import prompt main had — the flag is documented as non-interactive, and the checklist hint carries the command instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KWY36KMC5ZJSTSFN91GNF51T

https://entire.io/gh/entireio/cli/trails/771
What
First-time
entire enablenow proactively offers to import pre-existing agent history for the agents selected during setup, instead of leaving users to discover the hiddenentire import <agent>command themselves.Behavior
!settings.IsSetUpAny(ctx), captured before any settings are written. Re-enable never re-offers.AgentType, and limited to agents with ≥1 discoverable session (30-day lookback, same asentire import).--yesor no TTY): auto-imports all eligible selected agents, no prompt.enable.How
cmd/entire/cli/setup_import.go:maybeOfferSessionImport+ helpers, reusing the samestrategy.EnsureRedactionConfigured()+agentimport.Runflow as the standalone import command. Small test seams isolate orchestration from disk/TTY/checkpoint writes.strategy.EnsureSetup:runEnableInteractive(bare /--yes) andsetupAgentHooksNonInteractive(--agent). Both are reachable on re-enable, so thefirstRungate is load-bearing.Tests
setup_import_test.go): first-run gate, non-interactive auto-import, no-eligible no-op, interactive selection, empty-selection skip, importer-by-type matching.integration_test/enable_import_test.go): first-run enable imports a discoverable fixture, no-history is silent, re-enable does not re-offer.Verification
mise run lint— 0 issuesmise run test:ci— unit + integration + e2e canary all passNote
Medium Risk
Writes imported checkpoints to the metadata branch on first enable; failures are non-fatal but mistaken auto-import in CI/no-TTY paths could add unexpected history.
Overview
First-time
entire enablecan now pull in existing agent session history instead of requiring users to findentire importseparately.A new
maybeOfferSessionImportflow runs afterstrategy.EnsureSetupon both interactive enable andentire enable --agent <name>. It only runs when!settings.IsSetUpAny(ctx)is captured before settings are written, so re-enable never re-offers or re-imports. For each selected agent with a registered importer and discoverable sessions (30-day lookback, same as standalone import), interactive users get an optional multi-select with nothing pre-checked; non-interactive (--yesor no TTY) auto-imports all eligible agents. Import uses the sameEnsureRedactionConfigured+agentimport.Runpath asentire importand is best-effort—failures are logged and surfaced as notes but do not fail enable.Unit tests cover orchestration via injectable seams; integration tests cover first-run auto-import, silent no-op when no history, and no import on re-enable.
Reviewed by Cursor Bugbot for commit 885859c. Configure here.