Skip to content

hosted: execute registered external CLIs in hosted mode - #455

Merged
ankitranjan7 merged 15 commits into
mainfrom
feat/hosted-external-cli-passthrough
Aug 27, 2026
Merged

hosted: execute registered external CLIs in hosted mode#455
ankitranjan7 merged 15 commits into
mainfrom
feat/hosted-external-cli-passthrough

Conversation

@ankitranjan7

Copy link
Copy Markdown
Contributor

Summary

  • Registered external CLIs (gh, docker, vercel, wrangler, obsidian, ntn, tg, discord, lark-cli, plus anything the user registered locally) are not adapters — they are local binaries that Webcmd wraps for passthrough. In local mode they work; in hosted mode webcmd gh pr list fell through to the unknown-site branch and returned missingPluginGuidance('gh'), which fixes nothing.
  • Adds an injection seam on HostedRunnerOptions.externals and routes external names through it inside the !siteExists block, after the manifest is fetched (so a hosted site of the same name always wins) and before parseUnknownSiteRootOptions (so webcmd gh --version still forwards --version to gh instead of printing the webcmd version).
  • Exit codes travel out of dispatch via a dedicated ExternalExitSignal (not a CliError — a successful gh run must not render an error envelope), caught before the signal?.aborted → InterruptedError remap so a completed run under an aborted signal isn't misreported.
  • Refactors executeExternalCli to return the exit code instead of assigning process.exitCode, so the hosted test harness can observe it. Local caller updated to assign the returned value; no behavior change on the local path.

Test plan

  • Five new hosted-scope tests in `src/hosted/external.test.ts`: spawns + returns exit code, forwards `--version`, contacts Cloud only for the manifest (Cloud isolation), site wins over external of same name, unknown-and-not-external returns exit 2 with "not installed" stderr.
  • Three new unit tests in `src/external.test.ts` covering the new return-value contract.
  • Hosted suite green (635/635), typecheck clean, build clean.

Notes

  • Part 2 of 3 slices from a hosted-parity design. Independent of the other two (help/completion advertising, doctor exit contract) — no shared source files.

🤖 Generated with Claude Code

ankitranjan7 and others added 3 commits August 27, 2026 15:46
The hosted runner needs the numeric result to return through
runHostedCli, and process.exitCode is not observable in the hosted test
harness. No behavior change on the local path.
Externals are local binaries, not adapters: registry lookup, PATH check,
spawn. Nothing is sent to Cloud. Previously webcmd gh pr list returned
plugin-install guidance in hosted mode, which fixes nothing.

Resolved after the manifest so a hosted site wins over an external of the
same name, matching local precedence, and before the root-options parse so
--version still forwards to the external.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

🟠 Maintainer review suggested — low confidence

The automated review could not reach a fully supported conclusion.

This review is advisory and does not block merging.

@ankitranjan7
ankitranjan7 merged commit f7fec56 into main Aug 27, 2026
19 checks passed
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.

1 participant