Skip to content

fix(cli): refuse a non-URL install-from-source source up front - #3166

Merged
thymikee merged 3 commits into
callstack:mainfrom
LambdaTest:split/install-refusal
Oct 3, 2026
Merged

thymikee merged 3 commits into
callstack:mainfrom
LambdaTest:split/install-refusal

Conversation

@amankansal-lt

@amankansal-lt amankansal-lt commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Split out of #3118. This change affects every provider.

install-from-source treats its positional argument as a URL. Until now, a local path was only rejected later, by the download layer, with no pointer to the right command.

  • The CLI now refuses a source that is not an http(s) URL with INVALID_ARGS before doing any work, and points at install <app> <path>.
  • The deprecated SDK isTrustedInstallSourceUrl now reports an unparsable source as INVALID_ARGS instead of throwing a TypeError.

Validation

  • pnpm check:affected --run passes.

🤖 Generated with Claude Code

Review in cubic

install-from-source treats its positional as a URL. A local path is
only rejected later, when the download layer fails to parse it as a
source URL, and the error does not say what to run instead.

The CLI now refuses a positional that is not an http(s) URL with
INVALID_ARGS before any work and points at `install <app> <path>` for
local builds. The deprecated SDK `isTrustedInstallSourceUrl` reports an
unparsable source as INVALID_ARGS instead of throwing a TypeError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 4 files

Tip: cubic used a learning from your PR history. Let your coding agent read cubic learnings directly with the cubic MCP.

Re-trigger cubic

Comment thread packages/provision-kit/src/install-source.ts Outdated
Comment thread src/commands/management/install.ts Outdated
amankansal-lt and others added 2 commits October 3, 2026 18:22
…refix

The prefix check let `http://`, `https://` and `http://exa mple.com`
through, so they still failed later in the download layer without the
`install <app> <path>` hint. Parse the source with URL.parse and require
an http or https protocol, so every non-URL source is refused up front.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The download layer and isTrustedInstallSourceUrl each built the same
INVALID_ARGS "Invalid source URL" error. Build it in one place so the two
refusals cannot drift, and test that both reject an unparsable source
with the same code and message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thymikee

thymikee commented Oct 3, 2026

Copy link
Copy Markdown
Member

This PR is ready at f27001d. The CLI now refuses a non-URL install-from-source source up front, and the tests cover the cases from the issue.

Not blocking: the http(s) check in isHttpUrl (install.ts#L219) repeats the rule that provision-kit already owns, so the CLI and daemon messages can drift (for ftp://x they already differ). A small shared helper that throws invalidSourceUrlError() for unparsable input and the existing unsupported-protocol error otherwise would give one source of truth. The isTrustedInstallSourceUrl change from TypeError to AppError (install-source.ts#L161) is a separate SDK-facing change that is asserted twice and is not in the PR body. The error message also echoes the raw positional (install.ts#L208), so a value like ftp://user:pw@host/app would print its credentials. You can take or leave these.

Both cubic-dev-ai P3 threads are fixed at this head and can be resolved: the duplicated "Invalid source URL" payload is now one invalidSourceUrlError() (#3166 (comment)), and the prefix regex is replaced by a URL parse plus protocol check (#3166 (comment)).

CI shows one check, and it passes. I read the diff and did not run the tests locally. MCP, the SDK and direct daemon requests are not guarded by this change, which matches the CLI-only scope of the issue. Nothing blocks merge.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 3, 2026
@thymikee
thymikee merged commit fc7df6c into callstack:main Oct 3, 2026
13 of 14 checks passed
thymikee added a commit that referenced this pull request Oct 3, 2026
…token-attach-c41aff

* commit 'd396f3b509d9ed7cddaf170351ea6cf34e02ac16':
  fix(provider-webdriver): harden BrowserStack app references and endpoints (#3169)
  fix(android): back off a timed-out snapshot helper session and bound content re-captures (#3160)
  fix: centralize confirmed daemon retirement (#3126)
  fix: bind daemon registration writes to the acquired owner (#3125)
  fix: return confirmed daemon termination outcomes (#3124)
  refactor(move): share daemon registration and shutdown report modules (#3123)
  fix: preserve process lock exclusion across publication and reclaim (#3122)
  fix(cli): refuse a non-URL install-from-source source up front (#3166)
  fix(daemon): start a lease's TTL when its allocation completes (#3165)
  fix(android): fail doctor when adb is the Windows binary on a POSIX host (#3157)
  0.21.20
  0.21.19

# Conflicts:
#	src/daemon/server/daemon-runtime-metadata-ownership.test.ts
amankansal-lt added a commit to LambdaTest/agent-device that referenced this pull request Oct 5, 2026
Brings feat/testmu-provider-plugin (915e572) up to date with main,
which since landed the split-out callstack#3165 (lease TTL), callstack#3166 (install-from-source
URL refusal), callstack#3169 (BrowserStack app references, hub helpers, materialized
upload) and callstack#3173 (Limrun attached instances).

Main's reviewed versions win for the split-out code: appFileUploadForm with
{provider, service}, resolveHubAppReference with parseReference,
parseBrowserStackAppReference, isHttpUrl in install, the lease work pass only
when a provider allocates, and the upload file check in appFileUploadForm
rather than runtime-deployment. Re-applied on top only what the migration
needs: provider profile-field refusal (connect, WebDriver and Limrun
allocation, refused repeat allocation keeps its lease), optional auth on
fetchProviderVerificationJson for TestMu's public catalog, and the
provider-webdriver/plugin barrel without asRecord.

The TestMu plugin now uses asOptionalRecord from @agent-device/kernel/record,
parses lt:// references itself and uploads a public URL before delegating to
resolveHubAppReference, and passes {provider, service} to appFileUploadForm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants