Skip to content

feat(enable): offer to import agent history on first-time enable#1595

Merged
computermode merged 7 commits into
mainfrom
feat/offer-import-on-enable
Jul 7, 2026
Merged

feat(enable): offer to import agent history on first-time enable#1595
computermode merged 7 commits into
mainfrom
feat/offer-import-on-enable

Conversation

@computermode

@computermode computermode commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/771

What

First-time entire enable now proactively offers to import pre-existing agent history for the agents selected during setup, instead of leaving users to discover the hidden entire import <agent> command themselves.

Behavior

  • First-run only — gated on !settings.IsSetUpAny(ctx), captured before any settings are written. Re-enable never re-offers.
  • Agent-level granularity, scoped to the agents selected during enable, matched to importers by AgentType, and limited to agents with ≥1 discoverable session (30-day lookback, same as entire import).
  • Interactive: a multi-select with everything unchecked; confirming with nothing selected imports nothing.
  • Non-interactive (--yes or no TTY): auto-imports all eligible selected agents, no prompt.
  • Best-effort: discovery/import failures are logged and surfaced as a notice but never fail enable.

How

  • New cmd/entire/cli/setup_import.go: maybeOfferSessionImport + helpers, reusing the same strategy.EnsureRedactionConfigured() + agentimport.Run flow as the standalone import command. Small test seams isolate orchestration from disk/TTY/checkpoint writes.
  • Wired into both first-run enable paths after strategy.EnsureSetup: runEnableInteractive (bare / --yes) and setupAgentHooksNonInteractive (--agent). Both are reachable on re-enable, so the firstRun gate is load-bearing.

Tests

  • Unit (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 (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 issues
  • mise run test:ci — unit + integration + e2e canary all pass

Note

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 enable can now pull in existing agent session history instead of requiring users to find entire import separately.

A new maybeOfferSessionImport flow runs after strategy.EnsureSetup on both interactive enable and entire 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 (--yes or no TTY) auto-imports all eligible agents. Import uses the same EnsureRedactionConfigured + agentimport.Run path as entire import and 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.

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
Copilot AI review requested due to automatic review settings July 1, 2026 19:43

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread cmd/entire/cli/setup_import.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 maybeOfferSessionImport flow after strategy.EnsureSetup.
  • Add setup_import.go orchestration to discover eligible agents (by AgentType), 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.

Comment thread cmd/entire/cli/setup_import.go Outdated
Comment thread cmd/entire/cli/integration_test/enable_import_test.go Outdated
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
peyton-alt added a commit that referenced this pull request Jul 3, 2026
"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
peyton-alt added a commit that referenced this pull request Jul 3, 2026
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
@computermode computermode marked this pull request as ready for review July 6, 2026 16:07
@computermode computermode requested a review from a team as a code owner July 6, 2026 16:07
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
Comment thread cmd/entire/cli/setup_import.go Outdated
Comment thread cmd/entire/cli/setup_import.go
computermode and others added 2 commits July 6, 2026 12:14
… 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
@computermode computermode requested a review from pfleidi July 6, 2026 21:15
@computermode computermode merged commit a29161a into main Jul 7, 2026
10 checks passed
@computermode computermode deleted the feat/offer-import-on-enable branch July 7, 2026 00:42
peyton-alt added a commit that referenced this pull request Jul 7, 2026
… 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
peyton-alt added a commit that referenced this pull request Jul 7, 2026
…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
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.

3 participants