Skip to content

feat(cli): self update preserves install scope (local vs global)#1132

Merged
christso merged 2 commits intomainfrom
feat/1127-self-update-local
Apr 17, 2026
Merged

feat(cli): self update preserves install scope (local vs global)#1132
christso merged 2 commits intomainfrom
feat/1127-self-update-local

Conversation

@christso
Copy link
Copy Markdown
Collaborator

Summary

  • agentv self update now detects whether agentv was invoked from a local project dependency (process.argv[1] contains node_modules) or a global install, and runs the package manager with the matching scope:
    • Global (default): npm install -g agentv@latest / bun add -g agentv@latest
    • Local: npm install agentv@latest / bun add agentv@latest (no -g)
  • The detected scope is shown in the console output (e.g. Updating agentv using npm (local (project))...).

Implementation

  • apps/cli/src/self-update.ts
    • New helpers: detectInstallScopeFromPath(scriptPath) and detectInstallScope().
    • getInstallArgs() takes a scope parameter and emits ['install', pkg] / ['add', pkg] without -g for local.
    • performSelfUpdate() accepts an optional scope override (defaults to auto-detect) and returns the resolved scope alongside the existing fields.
  • apps/cli/src/commands/self/index.ts — passes the detected scope through to performSelfUpdate() and surfaces it in the Updating agentv using … log line.
  • apps/cli/test/self-update.test.ts — adds coverage for detectInstallScopeFromPath (local node_modules, npx cache, /usr/local/bin, .bun/bin, nvm, empty string).

Red/Green UAT

To exercise the spawn without actually installing anything, npm and bun were shadowed with fake shims that echo their received args; bun was invoked via an absolute path so PATH override only affects child processes.

Red (on main): Running performSelfUpdate from a script path under node_modules:

process.argv[1]: /tmp/fake-local-node_modules/node_modules/agentv-pretend/dist/cli-main.ts
FAKE-NPM-RECEIVED-ARGS: install -g agentv@latest

-g is used even though the invocation came from a local install — the reported bug.

Green (this branch):

  1. Local path (under node_modules/):
    process.argv[1]: /tmp/fake-local-node_modules/node_modules/agentv-pretend/dist/cli.ts
    FAKE-NPM-RECEIVED-ARGS: install agentv@latest
    Result scope: local
    
  2. Global path (no node_modules):
    process.argv[1]: /tmp/fake-global-path/cli-global.ts
    FAKE-NPM-RECEIVED-ARGS: install -g agentv@latest
    Result scope: global
    

Both cases behave as specified in the issue: local installs no longer get the -g flag, global installs still do.

Test plan

  • 10/10 apps/cli/test/self-update.test.ts pass (incl. 6 new cases covering detectInstallScopeFromPath)
  • Pre-push hooks: build, typecheck, lint, tests, validate-examples all pass
  • Manual red/green UAT captured above

Related

Closes #1127

Detect whether agentv was invoked from a local project dependency
(process.argv[1] contains node_modules) versus a global install, and
run the package manager install command with matching scope:

- Global (default): `npm install -g agentv@latest` / `bun add -g agentv@latest`
- Local: `npm install agentv@latest` / `bun add agentv@latest`

The `self update` command surfaces the detected scope in its console
output so users can see where the update is being applied.

Closes #1127
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 17, 2026

Deploying agentv with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6793914
Status: ✅  Deploy successful!
Preview URL: https://3b840ad3.agentv.pages.dev
Branch Preview URL: https://feat-1127-self-update-local.agentv.pages.dev

View logs

Address review feedback:
- Match `/node_modules/` (POSIX) or `\node_modules\` (Windows) as an
  actual path segment so paths that merely embed the substring
  (e.g. `/opt/my_node_modules_tool/`) aren't misclassified as local.
- Export `getInstallArgs` and assert the `-g` flag is present for
  global and absent for local, for both npm and bun.
- Add a Windows path case for `detectInstallScopeFromPath`.
- Reword the scope label in the console log to avoid nested parens.
@christso christso marked this pull request as ready for review April 17, 2026 02:41
@christso christso merged commit a5fce30 into main Apr 17, 2026
4 checks passed
@christso christso deleted the feat/1127-self-update-local branch April 17, 2026 02:41
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.

feat(cli): self update should update the same binary location (local vs global)

1 participant