Calm remaining error paths, low-friction env injection, dev-script port detection#5
Merged
Merged
Conversation
Three low-risk hardening fixes from a security review. None is exploitable today; each removes a latent footgun should an input source change. - ui.ts: validate the URL before openUrl hands it to a shell on Windows (`start` is a cmd builtin). Restrict to an https `*.vercel.run` origin with a shell-safe character set via a new exported `isOpenableUrl` predicate. - ready.ts: pass the loop count and port to the waitForPort probe as bash positional args ($1/$2) instead of string-interpolating them, matching the positional-arg pattern used elsewhere. - sync.ts: add `--` to the remote `rm -f` so no target can be read as an option (targets are always absolute, so this is belt-and-suspenders). Adds unit tests for isOpenableUrl and updates the removeFiles assertion. https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
Beta feedback showed raw HTTP 403 dumps with no guidance ("No clue why i
got this or what to even do"). v0.1.0-beta.3 calmed the `up .` auth paths;
this extends the same treatment to the paths it missed:
- `up stop` had none of the calm handling: an expired/invalid token dumped
the same raw 403 the feedback flagged. Route auth failures to the
sign-in note, and turn the very common "nothing to stop" case (sandbox
expired, or stop ran from a different directory than `up .`) into a
short explanation pointing at `up ls` instead of a raw 404/410 body.
- The sign-in note assumed the Vercel CLI is installed; `vercel login` is
a dead end for newcomers without it. Add a dim hint with the install
command and the VERCEL_TOKEN alternative.
- The dev-server timeout error never named the port it was waiting on. A
dev script that binds a different port (hardcoded -p, PORT ignored) hit
a 90s wait then an unexplained timeout. Name the port and point at
--port.
https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
Beta feedback: a user declined the .env.local prompt and their app (which needed those keys) ran broken, with a nag line on every later run and the flag required on each retry. A local dotenv almost always exists because the app needs it, so lean into that: - Default the .env.local prompt to yes; the common path is one Enter. - `--env-file` now records the choice, so passing it once re-enables injection on future runs (it also overrides an earlier "no"). - A recorded "no" stays quiet instead of printing the --env-file hint on every run; the hint shows only while no decision exists. - Drop the "!" on the env line of the shared-command trust panel; env injection is the expected case, not an alarm (sensitive-config keeps its warning since that genuinely persists in snapshots). https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
`up` waited on the framework's default port even when the project's dev script bound a different one (e.g. `next dev -p 4000`, `vite --port=8000`, `PORT=4000 node server.js`). Since `pm run dev` does not forward a port flag and a hardcoded port ignores the injected PORT env var, the server came up on its own port while the supervisor polled the default, ending in a 90s timeout for a project that needed no flags. Parse an explicit port out of the dev script (--port/-p/PORT=) and use it as the profile port so the supervisor waits where the server actually binds. Conservative matching: word-boundary guarded so `--prefix`, `npm-run-all -p`, and `run-p` are not misread, and out-of-range values are ignored. Falls back to the framework default when no port is present. https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
The message fallback /not[_ ]?found/i also matched ENOTFOUND, so `up stop` while offline would report "Nothing to stop" instead of the network error, leaving the user believing a still-running sandbox (and its public URL) was stopped. Match the API status (404/410) only, like the SDK does; anything else surfaces as a real error. https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
suarezesteban
pushed a commit
that referenced
this pull request
Jun 10, 2026
Ships the changes from #4 and #5: hardened command construction, calmer auth/stop/timeout error paths, low-friction env-file injection, and honoring an explicit port in the project's dev script. - Add the v0.1.0-beta.4 release artifacts (sha256-checksummed bundle). - Point install.sh's default version at v0.1.0-beta.4. - Print the next step after a successful install when no PATH change is needed, so the happy path ends with what to run instead of silence. https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
Merged
suarezesteban
added a commit
that referenced
this pull request
Jun 10, 2026
Ships #4 and #5: hardened command construction, calmer auth/stop/timeout error paths, low-friction env-file injection, and honoring an explicit port in the project's dev script. - Add the v0.1.0-beta.4 release artifacts (sha256-checksummed bundle). - Point install.sh's default version at v0.1.0-beta.4. - Print the next step after a successful install when no PATH change is needed. https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Completes the review work started in #4: calmer failure paths, lower-friction env injection, and dev-script port detection.
1. Calm the remaining raw-error paths (
39408d9)A raw
HTTP 403: FORBIDDENbody with no guidance is a dead end. v0.1.0-beta.3 calmedup .; this covers the paths it missed:up stopauth failures now route to the "Sign in to continue" note instead of a raw 403.up stopwith nothing to stop (expired sandbox, or run from a different directory thanup .) shows a short explanation pointing atup lsinstead of a raw 404/410 body.VERCEL_TOKENalternative, so it is actionable without the Vercel CLI installed.--port.2. Low-friction env-file injection (
446cba3)An app with a local dotenv almost always needs it to run; declining the prompt left the app broken and printed a hint line on every later run.
.env.localprompt defaults to yes — the common path is one Enter and the app just works.--env-filerecords the choice, so it sticks on future runs (and recovers from an earlier "no").--include-sensitive-configkeeps its warning, since that genuinely persists in snapshots).3. Honor a hardcoded port in the dev script (
623016d)upwaited on the framework's default port even when the dev script bound another (next dev -p 4000,vite --port=8000,PORT=4000 node server.js):pm run devforwards no port flag and a hardcoded port ignores the injectedPORT, so boot hit a 90-second timeout on a project that needed no flags at all. The explicit port is now parsed from the dev script so the supervisor waits where the server actually binds. Matching is conservative — word-boundary guarded so--prefix,npm-run-all -p, andrun-pare never misread, out-of-range values are ignored — and falls back to the framework default otherwise.4. Classify stop not-found by HTTP status only (
66f3053)The message fallback
/not[_ ]?found/ialso matchedENOTFOUND, soup stopwhile offline reported "Nothing to stop" instead of the network error — leaving the impression that a still-running sandbox (and its public URL) had been stopped. Only the API status (404/410) counts now, matching the SDK's own classification; anything else surfaces as a real error.Verification
pnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass; CI is green on this PR.https://claude.ai/code/session_01GVqD2pepFwpZG7dNp9T9jh