Skip to content

P6: unified setup wizard on hosted UAP installer - #183

Draft
777genius wants to merge 272 commits into
cursor/uap-installer-sdk-adapter-6c84from
cursor/uap-installer-wizard-6c84
Draft

777genius wants to merge 272 commits into
cursor/uap-installer-sdk-adapter-6c84from
cursor/uap-installer-wizard-6c84

Conversation

@777genius

@777genius 777genius commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Stacked on P4 (#182). Unified TTY/non-interactive wizard for install, inspect, update, repair, and uninstall of Claude and Codex through the hosted UAP installer.

This head (a77c333):

  • Inspect --json reports camelCase target fields (client, unit, outcome, configPath) matching Result/ReadinessFact/NextAction
  • Inspect reports discovered MCP ConfigPath on direct-mcp targets for both Claude and Codex, including omitted --agents
  • Text inspect prints mcp= (and profile= / digest= when set) so the read-only report shows the observed file
  • CLI contract test locks JSON ConfigPath and text mcp= for a selected-profile config.toml

Earlier on this PR:

  • Confirm-plan prints discovered codex-mcp= / claude-mcp= from an existing selected-profile file
  • After evaluate, a resolved MCP path is bound onto the request so Plan retry argv includes --mcp-config
  • Intent records mcpConfig for agent-notify targets; resume restores omitted --mcp-config; a different explicit flag is pending_intent_conflict
  • Bootstrap still does not invent --mcp-config on first argv; explicit --mcp-config / --claude-mcp-config still win
  • Windows install.sh E2E uses GNU timeout --foreground (or a child-PID watchdog) so a 5s unreachable-download timeout cannot SIGTERM the Git Bash test script
  • Explicit --mcp-config / --claude-mcp-config still win; otherwise a regular file already present in the selected profile ($CodexHome/config.toml, $ClaudeConfig/.claude.json) is handed off
  • Missing profile files stay empty so fresh installs skip handoff; HOME/cwd are not guessed; a directory at that path is not a config file
  • Bootstrap forwards already-selected CODEX_HOME as --codex-home when the flag is omitted
  • Inspect without --agents still reports both clients and does not offer request-permission; omitted --agents with --yes stays invalid / agents_required (exit 2) unless a matching pending intent restores them
  • Mixed live Install is Update of the behind sibling; Install of both when one client is already live on an older revision is Update then Add of the missing one
  • Same-bytes Install of the already-matching live sibling is Ready, not update_required
  • After mixed live siblings converge, ApplyGroup Install is restored
  • Windows install.sh E2E is capped at 10 minutes; Ubuntu/macOS go test -race uses a 20m package timeout
  • Retained r1→r2 is metadata-only SwitchRetained then Add; failed Add keeps data; Plan(Update) of retained skips permission/restart
  • Sequential Repair rematerializes a deleted older sibling without rewriting the live one
  • Attested Claude+Codex uninstall uses one UAP RemoveGroup; mixed Codex hold stays sequential

Native/reboot product E2E, Windows managedstdio 0111, unpublished UAP repository P1–P3/P5, group mixed rematerialize-after-delete (NativeObserver unset), and Cursor GitHub App write access to universal-agent-plugins remain out of this PR.

Open in Web Open in Cursor 

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.72462% with 957 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.96%. Comparing base (3914f92) to head (ebfb3e1).

Files with missing lines Patch % Lines
internal/agentnotify/portablesetup/uap.go 58.78% 121 Missing and 69 partials ⚠️
install/uapinstaller/group.go 69.93% 96 Missing and 48 partials ⚠️
internal/agentnotify/portablesetup/setup.go 39.56% 108 Missing and 31 partials ⚠️
cmd/claude-notifications/setup_wizard.go 72.54% 41 Missing and 29 partials ⚠️
internal/agentnotify/setupwizard/prompt.go 81.56% 45 Missing and 21 partials ⚠️
internal/agentnotify/portableasset/acquire.go 49.57% 32 Missing and 28 partials ⚠️
install/uapinstaller/switch_retained.go 51.40% 37 Missing and 15 partials ⚠️
install/uapinstaller/prepare.go 70.76% 19 Missing and 19 partials ⚠️
internal/agentnotify/setupwizard/codex_observe.go 58.69% 25 Missing and 13 partials ⚠️
internal/agentnotify/setupwizard/package.go 74.46% 19 Missing and 17 partials ⚠️
... and 10 more
Additional details and impacted files
@@                            Coverage Diff                            @@
##           cursor/uap-installer-sdk-adapter-6c84     #183      +/-   ##
=========================================================================
+ Coverage                                  65.26%   66.96%   +1.69%     
=========================================================================
  Files                                        181      194      +13     
  Lines                                      18657    23601    +4944     
=========================================================================
+ Hits                                       12177    15804    +3627     
- Misses                                      4676     5517     +841     
- Partials                                    1804     2280     +476     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cursor cursor Bot changed the title feat(notify): noninteractive setup-notifications wizard feat(notify): setup-notifications wizard with bootstrap routing Sep 14, 2026
cursoragent and others added 24 commits September 14, 2026 20:13
Plan §14.2 requires omitted uninstall to remove managed units, explicit
false to keep a unit, and uninstall without a package download or
delivery/permission proof. Keep readiness permission=unsupported.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
…ending

matchingReservation accepted any owner reservation, so uninstall could
resume an install handoff. Compare the stored intent action, keep the
pending install, and return conflict with the original retry command.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Action-only comparison let a Codex install reservation be resumed for
Claude. Require the stored target client before attaching the reservation.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
…sume

Store source digest on the install intent. A matching resume may omit it;
an explicit different digest is conflict. Wizard passes release version
and package SHA-256 through materialize.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Resume fills agents, units, profile, digest, and installation ID from the
stored handoff intent after the action uniquely matches. Explicit mismatches
stay conflict. Matching pending intent is confirmation, so --yes is not
required again. Persist the resolved client profile on the published intent.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Confirmed portable remove now writes the handoff reservation and resolved
profile before locator revoke. A matching resume can omit agents/--yes;
install during a pending uninstall stays conflict. Successful remove still
clears the reservation.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
UAP Codex remove requires a host attestation that the native plugin is
already gone or was never activated. Wizard --yes no longer invents that
fact. Uninstall without --external-uninstalled holds the removal
reservation, returns incomplete, and keeps the portable binding.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Portable install/remove always take the setup coordinator lease and run
kernel Recover before UAP Recover. Wizard uninstall no longer restores a
retired direct MCP, even when --mcp-config is still on the request.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Confirmed wizard install/uninstall now records the normalized SetupIntent
and kernel reservation before hooks or portable MCP effects. The wizard
keeps that reservation across clients and clears it only after the whole
operation completes. Incomplete Codex uninstall still leaves the intent.

Observe `codex plugin list --json` and, when that contract is recognized,
run `plugin remove` so --yes no longer has to invent ExternalUninstalled.
Unknown list output still holds the removal and asks for attestation.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
TTY confirmation now shows the resolved plan (action, agents, units, and
any mixed per-client flags) before mutation. Completed install/inspect
results offer restart, request-permission, and notify as explicit next
actions. Delivery stays not_verified until that test runs; uninstall does
not offer those setup steps.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
TTY FillInteractive now asks for hooks, agent-notify, or both before
showing the resolved plan. Confirmed install/uninstall reports coarse
phases to a host callback; the CLI writes those lines to stderr so JSON
stdout stays one result.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Plan §9.1.5: the application service preflights without publishing
intent or applying hooks/MCP, then TTY shows agents, profiles,
revision, and required follow-up actions before confirmation.
Mutation still requires --yes; Plan does not mutate the ledger.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
TTY Plan now runs a read-only UAP Prepare for agent-notify when a local
package root is present, shows the canonical source TreeDigest, and
closes the handle without Apply, Recover, or ledger mutation.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Plan now fetches the version-bound portable asset for notify preflight
and shows source-digest without leaving the temp root on Request.
Inspect reports pending UAP journals as recovery_required without
running Recover.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Plan stays ready so confirmed install can Recover, but the preflight
text and next actions now name pending journals. Recover itself still
does not invoke the helper runner or committed-binding callback.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
cursoragent and others added 30 commits September 15, 2026 18:16
Hybrid Install both with one live behind sibling keeps Update then Add.
Mixed live stays Update-only. Absent-second-client stays two-phase.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Noninteractive mutation with --yes but no --agents returned cancelled/empty_selection (exit 0). §9.2 requires an explicit selection or a matching pending intent; TTY empty choice is still canceled in FillInteractive. Also lock remaining §5.5.1 NextAction mappings and skip delivery offers after retained metadata-only Update.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Cover update/repair/uninstall and Plan, keep inspect of both clients
working without --agents, and skip delivery next-actions after uninstall.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Inspect without --agents still reports both clients as JSON exit 0.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Explicit --mcp-config/--claude-mcp-config still win. Otherwise a regular
file already present in the selected profile ($CodexHome/config.toml,
$ClaudeConfig/.claude.json) is used so bootstrap/TTY install can retire
existing direct MCP. Missing files stay empty so fresh installs skip
handoff; HOME/cwd are not guessed.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Cheap all-platform coverage for missing/regular/directory/relative/env
and explicit-wins. Unix install+inspect without --mcp-config retires
direct Codex MCP from the selected profile config.toml.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Flag --codex-home still wins. Otherwise the already-selected CODEX_HOME
env is forwarded so retry argv keeps the profile. HOME/.codex is not
guessed, and --mcp-config is still omitted so handoff uses an existing
selected-profile config.toml.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Windows 1.26 on a214b0d died in test_force_preserves_symlinks with
exit 3840 (SIGTERM) about five seconds into a run_with_timeout 5
install against 127.0.0.1:1. GNU timeout without --foreground can
signal the Git Bash test process; Windows timeout.exe is not a
command wrapper. Use --foreground, and otherwise watch only the
child PID.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
TTY confirmation already listed selected profiles. Existing
config.toml/.claude.json handoff was easy to miss unless --mcp-config
was set. Plan now prints codex-mcp/claude-mcp from the same discovery
path Run uses.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Omitted --mcp-config is resolved from the selected profile before the
intent is written. Resume restores that path, and a different explicit
flag conflicts. Hooks-only targets do not record MCPConfig.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Read-only inspect already discovers the selected-profile MCP file; include
that path on the direct-mcp TargetResult so --json reports the file that
was observed.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Omitted --agents inspect still observes both selected-profile files.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
TargetResult now matches Result/ReadinessFact/NextAction field names so
--json reports client/unit/outcome/configPath instead of PascalCase.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Co-authored-by: Илия <iliyazelenkog@gmail.com>
Inspect and uninstall results now surface PLUGIN_DATA retention when
the last live binding is gone. Absent inspect rows stay absent; the
flag is not a license to run the deleted binding.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Retained reinstall needs the existing Result.InstallationID. Inspect of
a single installation and uninstall of its last binding now copy that
id; empty inspect still omits it. Text output prints installation-id=
when the field is set.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
…data

After last uninstall the TTY sees no live bindings, so reinstall omits
--installation-id. The unique retained installation must still be reused.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
Partial setup already records InstallationID on the result. The retry
command now copies that reserved id so a later run does not allocate a
different installation.

Co-authored-by: Илия <iliyazelenkog@gmail.com>
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.

2 participants