Skip to content

2. migrate existing npm installs to the compiled agent - #2165

Merged
kevinjosethomas merged 1 commit into
mainfrom
feat/eng-6046-native-migration
Sep 12, 2026
Merged

2. migrate existing npm installs to the compiled agent#2165
kevinjosethomas merged 1 commit into
mainfrom
feat/eng-6046-native-migration

Conversation

@kevinjosethomas

@kevinjosethomas kevinjosethomas commented Sep 9, 2026

Copy link
Copy Markdown
Member

This is part of the PR stack migrating us to use Bun to compile Prime Agent for releases. This makes supported installations self-contained, removing the need to download and install Node.js and npm packages separately.

This PR moves existing users to the compiled version after they update and open Prime Agent again. Settings, credentials, and conversations stay intact. Unsupported machines continue using Node.js, and failed migrations leave the existing installation working. The old Node.js installation files are kept for now.

Tested this by simulating upgrades from ten previous releases (0.7.2 through 0.7.4, 0.8.0 through 0.8.1, and 0.9.0 through 0.9.4) to a simulated Bun-compiled release, including skipping straight to a later release. Also tested Alpine, which has no supported compiled package in this stack and automatically stayed on Node.js. An existing npm 12 restriction requires a documented recovery command.

ENG-6046 · Stack: #2140#2165#2166.


Note

Medium Risk
Changes the default npm CLI entrypoint and can download artifacts and replace the user's public command symlink; failures are designed to fall back to Node, but botched handoff or races could briefly affect how prime-agent is invoked.

Overview
Adds an npm-to-native migration bridge so users on conventional global npm installs can move to the compiled agent after updating, without losing settings or breaking launches when migration cannot complete.

Release packing (when --binary-dir is set) makes dist/bundle/cli.js the bridge, renames the real Node CLI to cli-node.js, and ships install.sh plus native-release.json in the npm tarball. On supported macOS/Linux global installs whose bin link still points at the package, the bridge can download/activate a managed release via the existing installer (foreground interactive only), reuse an equal-or-newer managed build after validation, and hand off the public command symlink to the native launcher while keeping Node as fallback. Daemon workers, --help/--version, piped/JSON runs, offline mode, unsupported hosts, competing npm installs, and failed/cancelled migrations are explicitly excluded or deferred.

Adds readNativeInstallation helpers, a long “Migration from npm” doc section (including npm 12 EALLOWREMOTE recovery), changelog notes, a large npm-native-bridge test suite, and small agent-traces test waits so uploads finish logging before assertions.

Reviewed by Cursor Bugbot for commit a6ecd39. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Migrate global npm installs to the compiled native agent launcher

  • Adds migrationTarget in npm-native-bridge.ts: for eligible interactive foreground launches on Darwin/Linux conventional global npm layouts, it downloads or reuses a compatible managed native release, validates platform and executable version, and hands off the public command link to the native launcher.
  • Falls back to the bundled Node CLI (cli-node.js) when migration is skipped or fails; opt-outs, offline mode, unsupported hosts, daemon/worker/version/help launches, and competing command owners all stay on Node.
  • Suppression is based on 24-hour timestamp marker files so failed migrations and probe diagnostics don't retry every launch; explicit retries bypass the window and cancellation removes the marker.
  • Adds readNativeInstallation and getNativeInstallation in native-installation.ts to validate managed installation layout, launcher target, checksum marker, release metadata, platform, and source URL before accepting it.
  • Updates pack-prime-agent-release.mjs so binary packages install the bridge as cli.js and retain the Node CLI as cli-node.js, shipping the installer and release metadata alongside.
  • Risk: foreground migration now spawns a detached installer (450s timeout) and forwards its output to stderr; if the shipped installer or release feed is misconfigured, users on conventional global npm installs will see stderr diagnostics and remain on Node until the 24-hour suppression window expires. Command-link handoff is exclusive with restoration on races, but a competing unrelated regular file at the command path is never overwritten.

Macroscope summarized a6ecd39.

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

Stale Bugbot comment from a previous run.

Comment thread packages/coding-agent/src/utils/native-installation.ts
Comment thread packages/coding-agent/src/utils/native-installation.ts
Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts Outdated
Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts

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

Stale Bugbot comment from a previous run.

Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts Outdated
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown

Prime Agent performance — completed

PR a6ecd39e compared with main dd760d31.

Overall: 0 regressed · 0 improved · 17 no clear change.

Metric Main This PR Change
Cold startup 1,270.0 ms 1,287.1 ms ≈ +17.1 ms (+1.35%)
Warm startup 764.0 ms 770.2 ms ≈ +6.2 ms (+0.82%)
Installation 12.28 s 12.12 s ≈ -0.16 s (-1.27%)
Compressed release artifacts 70.06 MB 69.93 MB ≈ -0.13 MB (-0.19%)
Installed footprint 571.90 MB 571.91 MB ≈ +0.0034 MB (+0.00%)
Idle memory, summed RSS 1,104.81 MB 1,095.23 MB ≈ -9.58 MB (-0.87%)

Python runtime

Metric Main This PR Change
Python kernel startup 120.1 ms 118.7 ms ≈ -1.5 ms (-1.21%)
Python cell round trip 0.472 ms 0.470 ms ≈ -0.002 ms (-0.39%)
Empty bash command 10.3 ms 9.9 ms ≈ -0.4 ms (-4.15%)
Bash git status 15.4 ms 14.5 ms ≈ -0.8 ms (-5.47%)
Bash 32 KiB output 10.7 ms 10.3 ms ≈ -0.4 ms (-3.73%)
35 cells / 9 shell calls 154.4 ms 146.6 ms ≈ -7.7 ms (-5.01%)
Python interrupt to done 1.437 ms 1.420 ms ≈ -0.017 ms (-1.18%)
Python state snapshot 24.6 ms 24.4 ms ≈ -0.2 ms (-0.97%)
Python state restore 346.4 ms 319.5 ms ≈ -26.9 ms (-7.76%)
Python idle RSS 35.84 MB 35.29 MB ≈ -0.55 MB (-1.54%)
Python RSS after pandas workload 97.96 MB 97.96 MB ≈ +0.00 MB (+0.00%)

Sandbox cost: ~$0.0712 — no inference calls.
Run, logs, and downloadable raw results

Methodology and samples

Main resolved at 2026-09-12T08:05:46.939799+00:00. Harness dd760d31.
Linux x64, 4 vCPU, 8 GB RAM, 20 GB disk; region us.
Image: node:24-bookworm@sha256:be23f54a88d34e8824c741b19b91064094f92c1c97b194144bfc8b50d67258e2.
Stock tools, skills, daemon, and Python bootstrap enabled; fresh homes and a fixed Git fixture.
Onboarding is dismissed; the editor starts without a selected model or submitted prompt.
Medians shown. Arrows require a 20% timing/memory change plus absolute floors and IQR.
These practical noise floors are not a statistical significance test.
Cold means stopped Prime processes; OS filesystem caches are not flushed.
No model requests or credentials. Installation excludes build/setup time.
Installer tarballs use loopback; npm/Python downloads use the network with fresh caches.
Artifact size counts release tarballs; footprint after first use includes registry packages.
MB is decimal. Summed RSS can double-count shared pages; PSS is recorded when available.
Provisioning, setup, and build durations are recorded separately in the raw results.
Kernel probes use the installed JSONL runtime, outside the TUI/TypeScript host.
Per trial: 50 Python cells, 5 calls per shell case, and one 35-cell mix (9 git status calls).
Cell/shell values are batch means; other runtime timings are single operations.
State fixture: a 10,000-row × 8-column integer DataFrame and a 10,000-integer list.
Restore runs in a fresh kernel, including pandas imports; kernel startup is excluded.
Kernel RSS covers the isolated Python process; loaded RSS follows the pandas workload.
Costs estimate full sandbox lifetimes at configured rates, including setup and build.
Budget target: $1; not a billing cap. Checks are informational.

Metric Main successful/attempted PR successful/attempted Main spread PR spread
Cold startup 10/10 10/10 IQR 20.1 ms IQR 20.0 ms
Warm startup 10/10 10/10 IQR 9.7 ms IQR 17.0 ms
Installation 3/3 3/3 range 0.34 s range 0.25 s
Compressed release artifacts 1/1 1/1
Installed footprint 1/1 1/1
Idle memory, summed RSS 10/10 10/10 IQR 78.77 MB IQR 68.74 MB
Python kernel startup 10/10 10/10 IQR 2.2 ms IQR 3.0 ms
Python cell round trip 10/10 10/10 IQR 0.010 ms IQR 0.019 ms
Empty bash command 10/10 10/10 IQR 0.4 ms IQR 0.4 ms
Bash git status 10/10 10/10 IQR 0.5 ms IQR 0.5 ms
Bash 32 KiB output 10/10 10/10 IQR 0.4 ms IQR 0.6 ms
35 cells / 9 shell calls 10/10 10/10 IQR 9.6 ms IQR 4.7 ms
Python interrupt to done 10/10 10/10 IQR 0.099 ms IQR 0.176 ms
Python state snapshot 10/10 10/10 IQR 0.8 ms IQR 0.6 ms
Python state restore 10/10 10/10 IQR 22.5 ms IQR 7.2 ms
Python idle RSS 10/10 10/10 IQR 1.88 MB IQR 3.06 MB
Python RSS after pandas workload 10/10 10/10 IQR 2.23 MB IQR 3.67 MB

@snimu

snimu commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

npm-native-bridge.ts: First launch after an update looks hung for up to 7.5 minutes with zero output, because the bridge runs install.sh synchronously on any non-internal invocation — including --version, --help, and automation/scripts — with its output piped and discarded. A Ctrl-C during it writes the retry file, which locks migration out for 24 hours. The internal skip list also misses owned-session workers and the interactive update child, so background workers can trigger or inherit the silent download.

[written by prime-agent, checked by snimu]

@snimu

snimu commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

--native-platform / --version probe contract: Any drift in either probe output — install.sh --native-platform must print exactly 'os-arch' and the compiled binary's --version must print bare semver — silently keeps every npm user on Node forever: a probe mismatch is a permanent quiet deferral, with no error anywhere. No test pins the real outputs; the test stub prints the expected strings by construction. The producer side has matching sharp edges in #2140's install.sh: --native-platform prints without a trailing newline and exits 1 silently on unsupported platforms.

[written by prime-agent, checked by snimu]

Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts

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

Stale Bugbot comment from a previous run.

Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts

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

Stale Bugbot comment from a previous run.

Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts
@kevinjosethomas kevinjosethomas changed the title migrate existing npm installs to the compiled agent 2. migrate existing npm installs to the compiled agent Sep 12, 2026
@kevinjosethomas
kevinjosethomas force-pushed the feat/eng-6046-native-migration branch from 2ccbac7 to e91abad Compare September 12, 2026 03:37

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

Stale Bugbot comment from a previous run.

Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts

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

Reviewed by Cursor Bugbot for commit fbf370e. Configure here.

Comment thread packages/coding-agent/src/cli/npm-native-bridge.ts Outdated
@kevinjosethomas
kevinjosethomas force-pushed the feat/eng-6046-native-migration branch from 88bd3b2 to 202b363 Compare September 12, 2026 07:18
Base automatically changed from feat/eng-6027-standalone-binaries to main September 12, 2026 07:59
@kevinjosethomas
kevinjosethomas force-pushed the feat/eng-6046-native-migration branch from 202b363 to a6ecd39 Compare September 12, 2026 08:05
@kevinjosethomas
kevinjosethomas merged commit 5a3b922 into main Sep 12, 2026
26 checks passed
@kevinjosethomas
kevinjosethomas deleted the feat/eng-6046-native-migration branch September 12, 2026 08:16
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