Launch targets
September 16, 2026 · View on GitHub
This document defines how edgee launch <target> names are chosen and how they
relate to credentials, transport, and the hidden edgee relay command.
Read this before adding a new agent.
Why the catalogue matters
Wrapping the agent itself — with no code change on the user's side — is Edgee's core differentiator against app-oriented gateways. Every target added here widens the surface Edgee can route, meter, and govern. The catalogue below is also the foundation the upcoming desktop app builds on: it will wrap the whole local AI stack, CLI agents and desktop apps alike, from these same definitions.
So target names are long-lived public API. Renaming one breaks user aliases, desktop wrappers, scripts, and docs at once. Get the name right the first time.
Three layers (do not conflate them)
| Layer | What it is | Examples |
|---|---|---|
| Launch target | Public CLI name (edgee launch …) | claude, cursor, copilot-vscode, claude-desktop, later copilot |
| Provider key | Edgee credentials / console API key slot | claude, claude_desktop, cursor, copilot |
| Transport | How traffic reaches the gateway | CLI env-injection, MITM relay, … |
Users only see launch targets. Transport stays an implementation detail
(edgee relay remains hide = true). Several targets may share one provider
key (e.g. copilot-vscode today and future copilot CLI → provider copilot).
Surfaces may instead be split into their own backend agent when their usage
should be metered separately: claude-desktop is a dedicated claude_desktop
agent (own key + compression), distinct from claude (Claude Code).
Naming convention
1. Bare name = primary surface
Usually the official CLI of that product:
claude | codex | opencode | codebuddy | crush | pi | omp | kimi | kilo | copilot | …
Reserve the bare product name for the CLI even if the CLI ships later. If only an IDE/app surface exists today, use a suffixed name (see below) so the bare name stays free.
Exception: copilot-cli deliberately breaks this rule — see
its section
for why. Bare copilot stays unclaimed rather than pointing at it.
2. Suffixed name = another surface of the same product
Pattern: <product>-<surface>
copilot-vscode
claude-desktop
claude-vscode
codex-desktop
Do not overload the bare name with flags (edgee launch claude --desktop).
Each surface gets its own subcommand so help, scripts, and aliases stay obvious.
3. Distinct product = distinct bare name
When the product is not “another skin” of an existing CLI:
cursor # Cursor IDE (no separate CLI target yet)
Avoid ambiguous host-only names like bare vscode as a canonical target —
VS Code can host Copilot, Claude Code, etc. Prefer copilot-vscode, and later
claude-vscode, not a single vscode catch-all.
Exception: intellij is the chosen public target for IntelliJ IDEA. It currently
routes the GitHub Copilot plugin, shares the copilot provider key, and does not
imply support for other AI plugins in the IDE.
4. Aliases are optional discoverability only
Aliases may exist for muscle memory (vscode-copilot → copilot-vscode) but the
canonical name in docs, README tables, and new code is the one above.
Do not alias a reserved bare CLI name (copilot) to a suffixed surface.
Current catalogue
CLI agents (env → gateway)
| Target | Product | Provider key |
|---|---|---|
claude | Claude Code CLI | claude |
codex | Codex CLI | codex |
opencode | OpenCode CLI | opencode |
codebuddy | CodeBuddy CLI | codebuddy |
crush | Crush CLI | crush |
pi | Pi CLI | pi |
omp | Oh My Pi CLI | pi |
kimi | Kimi Code CLI | kimi |
kilo | Kilo Code CLI | kilo |
Apps & editors (relay today)
| Target | Product | Provider key | Notes |
|---|---|---|---|
cursor | Cursor IDE | cursor | Relays the cursor binary |
intellij | GitHub Copilot in IntelliJ IDEA | copilot | Direct IDE launch with proxy env + Node CA; live-session validation pending |
copilot-vscode | GitHub Copilot in VS Code | copilot | Relays code; aliases: vscode-copilot, vscode, code |
copilot-desktop | GitHub Copilot app (macOS, local sessions) | copilot | Direct app-bundle launch; proxy env + dedicated system-trusted Copilot CA |
copilot-cli | GitHub Copilot CLI | copilot | Relays the copilot binary directly (TUI, no --wait) — deliberately not env-injected; see below |
claude-desktop | Claude Desktop (Claude Code only) | claude_desktop | Launches the Claude app bundle behind the relay; dedicated agent (own key + Claude compression flavor), not shared with claude (Claude Code). Routes api.anthropic.com/v1/messages; the app's own chat goes to claude.ai and is not covered — see below |
codex-desktop | ChatGPT desktop app (Codex tab only) | codex | No relay. Its backend is a bundled codex app-server reading $CODEX_HOME/config.toml; the Edgee provider is written there, the app is launched, and the file is restored when the app quits. See below. |
Desktop chat apps route the coding surface, not the chat surface
Both vendor desktop apps ship two things: a coding agent that speaks the public API, and a chat client that speaks the vendor's consumer web backend. Edgee routes the first and cannot see the second. This is one pattern, not two bugs, and it is worth checking for on any future app target.
| Target | Routed | Not routed | Why |
|---|---|---|---|
claude-desktop | Claude Code → api.anthropic.com/v1/messages | the app's chat → claude.ai/api/organizations/{org}/chat_conversations/{uuid}/completion | claude.ai is absent from INFERENCE_HOSTS, and the System-keychain CA is name-constrained to anthropic.com |
codex-desktop | Codex tab → config.toml model_provider | ChatGPT tab → chatgpt.com/backend-api/f/conversation | the ChatGPT tab never enters codex app-server, so no config surface reaches it |
Both verified by packet capture on 2026-08-26. In each case a full chat exchange produced zero requests on the routed path.
Neither is a host-list edit away from working:
claude-desktopwould need the CA widened fromanthropic.comto coverclaude.ai. That CA is a persistent, machine-wide trust root, deliberately constrained so that a leak could vouch for nothing else.claude.aihosts the user's entire Claude web session. Security decision, not configuration.codex-desktopwould need a relay plus gateway support for the ChatGPT thread protocol, and re-originates a session guarded bysentinel/heartbeatand device attestation.
What the two chat surfaces report differs, and it matters for what is even worth
building. Neither reports token counts — Claude Desktop uses the standard Anthropic SSE
envelope with usage stripped out. But Claude's message_limit event carries
authoritative quota utilization per 5-hour and 7-day window on every turn, whereas the
ChatGPT tab exposes only feature quotas (deep_research, image_gen). If chat routing
is ever revisited, Claude Desktop is the stronger candidate.
Keep the surface limit in the launch hints (print_claude_desktop_hint,
codex_desktop::print_launch_hint). Without it, "launching the app through Edgee" reads
as covering the whole app — which is exactly how this was first reported as a bug.
codex-desktop — config patch, not relay
The ChatGPT desktop app embeds Codex (ChatGPT.app/Contents/Resources/codex,
launched as app-server over stdio) and honors base_url + http_headers from a
model_providers entry — the very settings launch codex passes as -c overrides.
So this target needs no proxy, no MITM CA and no system-keychain trust.
Scope: the Codex tab, not the whole app
The app's ChatGPT tab is out of reach of this mechanism and always will be. It is
the ChatGPT web client running in the app's bundled Chromium: it POSTs
chatgpt.com/backend-api/f/conversation from Chromium's own network stack and never
enters codex app-server, so it never reads config.toml and model_provider cannot
route it. Those turns bill OpenAI directly and are invisible to Edgee.
Established by packet capture (2026-08-26, codex 0.147.0 / Codex Desktop
0.149.0-alpha.4.3). Over 37 minutes spanning a complete ChatGPT-tab exchange, the
app-server sent the gateway nothing but its 3-minute GET /v1/models poll — no
POST /v1/responses — and wrote no sessions/**/rollout-*.jsonl, which it does for
every conversation it actually runs. A Codex-tab turn in the same session produced both,
with model_provider = edgee-cli.
Do not try to fix this with a wider config patch; there is no config surface to patch.
Routing it would take a relay MITM'ing chatgpt.com, and two things make that a
product decision rather than a port of claude-desktop:
- Different wire format.
f/conversationis the ChatGPT thread protocol (conversation_id/parent_message_id, server-held state), not the Responses API, so it cannot simply be added toREROUTE_MAPinrelay/handler.rs— the gateway would have to speak it and translate both directions. - Anti-automation. A single ChatGPT-tab turn carries
POST /backend-api/sentinel/heartbeatandGET /backend-api/ios/attestation_challenge. The Codex tab's/backend-api/codex/responsespath carries neither. Rewriting or re-originating those requests is what that machinery exists to detect, and the exposure lands on the user's ChatGPT account.
print_launch_hint states the limitation at launch. Keep it there: without it, "launching
the ChatGPT desktop app through Edgee" reads as covering the whole app, which is exactly
how this got reported as a bug.
Three constraints are load-bearing, each established empirically:
- The config file is the only lever. The app supplies its own argv
(
-c features.code_mode_host=true app-server), so-cinjection is impossible.--profile <name>is the design you'd want — it layers$CODEX_HOME/<name>.config.tomland never touches the user'sconfig.toml— but it is argv-only: noCODEX_PROFILEenv var exists, and the legacyprofile = "…"config key is a fatal startup error in 0.147 ("no longer supported; use--profile"). If a future codex honors an env var for this, switch to it — it removes the only invasive part of this integration. - Never point
CODEX_HOMEat a private copy. It does propagate into the spawned child, but a second home means a secondauth.json, and the ChatGPT OAuth refresh token is single-use/rotating — whichever copy refreshes first invalidates the other and the user must sign in again. Symlink/hardlink does not help either: codex removes and atomically replaces the file. And auth cannot come from the environment —CODEX_ACCESS_TOKENis an agent-identity slot, so it would force API-key billing instead of the user's ChatGPT plan. - The app re-reads
config.tomlon every new conversation. The app-server builds a freshConfigper conversation rather than caching one at startup, so the patch has to stay in place for as long as the app runs. This was originally implemented the other way — patch, wait ~10s, revert — and only the first auto-opened conversation went through Edgee while every later tab silently billed OpenAI directly.~/.codex/sessions/**/rollout-*.jsonlis the ground truth: each file'ssession_meta.model_providerisedgee-clioropenai, per conversation. Check it before changing this lifecycle again.
So the lifecycle is patch → spawn → supervise until the app quits → restore. Three consequences fall out of holding the patch that long:
- The command runs as long as the app does. The terminal must stay open; the launch hint says so.
- Ctrl-C restores and exits without killing the app. Killing an app the user is working in would be worse than degrading to direct OpenAI, so it warns instead that new tabs are no longer routed.
- A bare
codexCLI run is routed too, on the desktop key.edgee launch codexis unaffected — its-coverrides win over the config file.
A stranded patch (terminal closed, crash) is undone by the leftover-backup recovery at
the top of run() on the next launch, so the invasive window is bounded even though it
is no longer short.
The grace period is a timer, not a signal — we cannot observe codex reading the file. It polls so the single-instance handoff is caught early. If a cold start ever exceeded it, the app would read the reverted config and talk to OpenAI directly: no compression, no metering, nothing broken, but also no warning.
Restore is surgical, not a rollback: codex rewrites config.toml at runtime
(project trust_levels, plugin state, [desktop] prefs), so the managed block is
stripped from the current file rather than restoring the backup snapshot, which
would discard the user's session. The backup remains for crash recovery and for the
case where codex reserializes the file and drops our marker comments.
The gateway must match the app's User-Agent (Codex Desktop/…) case-insensitively
for the Responses passthrough to fire; a case-sensitive starts_with("codex") sent
every desktop request down the keyed pipeline, which authenticates from
Authorization — the app's ChatGPT OAuth JWT — and 401'd.
opencode — Edgee provider or existing subscription
edgee launch opencode adds Edgee as a provider in a temporary merged config.
OpenCode sends those requests directly to the gateway using the Edgee key.
The hidden edgee relay opencode path serves a different use case: it launches
OpenCode with the user's config unchanged and proxies supported inference traffic
through Edgee in passthrough mode. Existing provider credentials remain attached
to the request, including a GitHub Copilot token selected through OpenCode. The
relay uses the opencode Edgee key for agent attribution and also intercepts the
Copilot inference and token-discovery hosts.
pi and omp — additive provider in each agent's own config
opencode and crush build a merged config in $TMPDIR and point the agent at
it (OPENCODE_CONFIG, CRUSH_GLOBAL_CONFIG), so the user's files are never
touched. Pi has no such lever, and the one that looks like it is a trap:
PI_CODING_AGENT_DIR relocates the entire agent directory — models.json
but also auth.json, settings.json, keybindings.json, sessions/,
themes/, tools/, prompts/, bin/, plus extension, skill and plugin
discovery. Pointing it at a temp dir launches pi with no history, no logins, no
settings and none of the user's plugins. --models is not an alternative: it
takes model patterns for Ctrl+P cycling, not a config path.
So pi writes into ~/.pi/agent/models.json, while omp writes into
~/.omp/agent/models.yml. Both use two managed keys: providers.edgee for
Chat Completions and providers.edgee-anthropic for Anthropic Messages. Custom
providers merge into pi's built-in catalog by provider + id, so the block is
purely additive — nothing the user already had is overridden. That is what
makes it safe to leave in place, and why there is no patch-and-revert dance like
codex-desktop: this adds a provider rather than hijacking one the user depends
on.
OMP is Pi-compatible and reuses the pi coding-agent key. Sessions therefore
share Pi's backend attribution and settings rather than provisioning another
key.
Three details are load-bearing:
- Env references are
$NAME, and this requires pi ≥ 0.79.4. That release deliberately reversed the syntax (upstream #5661): before it, the whole value was the variable name (bareEDGEE_API_KEY) and an unset variable fell through to the literal string; from it, bare uppercase values are literals and$NAMEis the only env reference. The two spellings are mutually exclusive — each is an inert literal on the other side of that boundary — and both fail identically, with the gateway answering 401 because it was handedEDGEE_API_KEYor$EDGEE_API_KEYas a credential. Check the pi version first when debugging a 401 here. - The Edgee key is therefore never written to disk — the config stores the
references
$EDGEE_API_KEY/$EDGEE_SESSION_IDand launch supplies the values. This is strictly better than the OpenCode and Crush temp configs, which embed the key. The trade-off: a barepirun sees the Edgee models but cannot authenticate them. - An empty gateway model list is fatal here, unlike for OpenCode. A pi custom
provider is defined by its models, so registering one with none opens the
session on "No models available".
fetch_gateway_modelsis best-effort and returns empty on any failure (an unreachable gateway, e.g. a dev profile pointing at alocalhostport with nothing on it), so launch bails before writing rather than leaving a dead provider in the user's config. - The catalog is split by ingress protocol. Models whose IDs start with
anthropic/useapi = "anthropic-messages"with the gateway root as their base URL, so Pi appends/v1/messagesand applies its native prompt caching. Every other model usesapi = "openai-completions"with a/v1base URL, so Pi appends/chat/completions. Gateway reroutes still work from either ingress.
Reasoning-capable models are declared with reasoning: true and a model-level
thinkingLevelMap generated from the catalog. Unsupported Pi levels are set to
null, so the picker hides and skips them; catalog none maps to Pi's off
slot. On the Anthropic provider, compat.forceAdaptiveThinking is enabled: Pi
sends thinking.type=adaptive plus the exact effort, and the gateway translates
that canonical control for whichever provider ultimately serves the request.
kimi — the env-only channel Kimi Code leaves open
Kimi Code refuses to read provider credentials from the shell on purpose:
api_key / base_url come from config.toml (or its [providers.<n>.env]
sub-table), and export KIMI_API_KEY=… does nothing. So the lever every other
CLI target uses is closed here — except for one documented exception, the
KIMI_MODEL_* family, "an explicit channel that does read credentials from
the shell".
Setting KIMI_MODEL_NAME makes kimi synthesize a provider and a model alias
in memory, outranking default_model in config.toml and evaporating with the
process. Four variables are all this target needs:
KIMI_MODEL_NAME=moonshotai/kimi-k2.7-code # also the enable switch
KIMI_MODEL_API_KEY=<edgee key>
KIMI_MODEL_BASE_URL=https://api.edgee.ai # no /v1 — the SDK appends it
KIMI_MODEL_PROVIDER_TYPE=anthropic
That makes kimi the cleanest CLI target after claude: nothing is written to
the user's files, so there is no additive block to maintain (pi) and no
patch-and-revert dance (codex-desktop), and a bare kimi run afterwards is
completely unaffected.
Three details are load-bearing:
base_urltakes no/v1.KIMI_MODEL_PROVIDER_TYPE=anthropicselects Kimi's Anthropic Messages implementation, which appends/v1/messagesitself — the same rule asANTHROPIC_BASE_URLfor Claude Code andbaseUrlfor pi.- The Edgee key travels as the provider credential, not as
x-edgee-api-key. The gateway resolves a key fromx-api-keyorAuthorization: Bearer, and answers 401 tox-edgee-api-keyon its own.KIMI_MODEL_API_KEYlands in the former, so it authenticates; there is nothing to add. KIMI_MODEL_NAMEis the enable switch, and a missing required variable is fatal. Kimi fails at startup rather than quietly falling back to Moonshot, so a half-configured launch is loud instead of silently unmetered.
Session attribution rides KIMI_CODE_CUSTOM_HEADERS
KIMI_MODEL_* carries no headers of its own, but Kimi Code 0.20.2 added
KIMI_CODE_CUSTOM_HEADERS — one Name: Value per line, applied to outbound LLM requests. Same
shape as ANTHROPIC_CUSTOM_HEADERS, so this target sends the full Edgee header set and sessions
group in the console exactly as they do for Claude Code.
The variable was not in the docs site's environment-variables reference at the time of writing —
only in the 0.20.2 release notes. Verified on the wire against a loopback server: x-edgee-api-key,
x-edgee-session-id and x-edgee-repo all arrive on POST /v1/messages?beta=true, alongside the
x-api-key that KIMI_MODEL_API_KEY produces. If a future release drops the variable, the fallback
is an additive [providers.edgee] block with custom_headers in the user's config.toml, the way
pi.rs writes models.json — but note custom_headers values take no $NAME env references, so
the key would then sit on disk, and a per-launch session id in a shared file races between
concurrent launches.
kilo — inline config, nothing written anywhere
The Kilo Code CLI is an OpenCode fork: same config schema, same lowercase tool
names, same 32k OUTPUT_TOKEN_MAX clamp. So the obvious implementation is
opencode.rs with KILO_CONFIG swapped in for OPENCODE_CONFIG.
Kilo has a better lever. KILO_CONFIG_CONTENT takes the config as an inline
JSON string and sits near the top of the precedence chain:
remote well-known → ~/.config/kilo/kilo.json → KILO_CONFIG → ./kilo.json
→ .kilo/kilo.json → KILO_CONFIG_CONTENT → managed (deep-merged, later wins)
Two things follow, neither available to the $TMPDIR targets:
- The key never touches disk.
opencodeandcrushwrite the Edgee key into a temp config and unlink it on exit; a crash in between leaves it on disk. Here it exists only in the child's environment. - Kilo does the merge.
opencode.rshas to find and parse the user'sopencode.json/.jsoncitself — that is what its JSONC stripper is for — so it can re-emit their settings alongside ours.KILO_CONFIG_CONTENTis merged over whatever the user already has, so this target emits oneprovider.edgeekey and reads nothing. Sitting above the project layer also means a repo-localkilo.jsoncannot shadow the Edgee provider.
KILO_CONFIG_DIR is a trap, and an unusually well-disguised one: the
configuration reference embedded in the binary calls it "appended to the search
list", which would make it the natural home for delivered skills and agents. The
binary resolves config: KILO_CONFIG_DIR ?? Hc.config — it replaces the
global config root, hiding the user's own commands, agents and skills. Where the
docs and the binary disagree, the binary wins.
Like opencode and crush, and unlike claude and codex, this target runs
entirely on Edgee-supplied credentials — it does not redirect an agent the
user already authenticated. kilo auth is left alone and unused on this path.
copilot-cli — relay, not env injection: the BYOK lever costs the user their plan
The obvious lever, COPILOT_PROVIDER_BASE_URL (+ COPILOT_PROVIDER_TYPE /
COPILOT_PROVIDER_API_KEY / COPILOT_PROVIDER_HEADERS), is real and works —
verified end to end against a loopback mock: it POSTs standard /v1/messages
Anthropic-shaped requests carrying whatever headers COPILOT_PROVIDER_HEADERS
sets. But per copilot help environment, setting it "uses this provider
instead of GitHub Copilot's model routing. GitHub authentication is not
required." That's the same trap as codex-desktop's ChatGPT tab, just in CLI
form: the env-injection path doesn't meter the user's paid Copilot seat, it
replaces it with a bare BYOK shell pointed at Edgee — architecturally identical
to kimi/pi, not to claude/codex.
So this target relays instead, following copilot-vscode (they share the
copilot provider key and both MITM COPILOT_ONLY_HOSTS —
githubcopilot.com + api.github.com). That's also why it's named
copilot-cli rather than bare copilot, breaking rule 1's "reserve the bare
name for the primary CLI": its transport and passthrough semantics pair it with
copilot-vscode as another surface of the same product, not with the
direct-env-injection CLIs (claude, codex, kimi, …). Bare copilot stays
unclaimed.
Two things made relay viable here, verified directly against the installed
@github/copilot 1.0.83 binary (no real GitHub account available, so the
verification stops at the transport layer — TLS trust and proxying — not the
full authenticated request/response cycle):
- Native (non-BYOK) traffic honors
HTTPS_PROXY. With a well-formed but invalid fine-grained PAT (GITHUB_TOKEN=github_pat_…), the CLI issuedCONNECT api.github.com:443straight through a logging proxy before failing on the token check — confirming the standard proxy env is read before GitHub auth is attempted, not bypassed by some hardcoded transport. - It honors
NODE_EXTRA_CA_CERTS. A BYOK request pointed at a local HTTPS mock signed by a throwaway CA failed TLS verification untilNODE_EXTRA_CA_CERTSwas set to that CA's cert, then succeeded — the same mechanismclaude,copilot-vscode, andcursoralready rely on for relay MITM trust (seespawn_agent). Native model requests use a stricter platform verifier, so the dedicated, name-constrained Copilot CA is also installed in the macOS system keychain on first launch.
Net effect: edgee launch copilot-cli spawns copilot directly (TUI-style, no
--wait, same as claude/codex) with the relay's proxy env and CA, and its
real Copilot-billed traffic to githubcopilot.com/api.github.com reroutes
through the gateway — preserving the user's actual GitHub Copilot subscription,
which the BYOK lever cannot do.
Planned targets (same rules)
| Target | Product | Likely provider | Likely transport |
|---|---|---|---|
claude-vscode | Claude Code in VS Code | claude | Relay or native config |
Checklist for a new target
- Pick the canonical launch name with the rules above.
- Add
src/commands/launch/<name>.rs(use underscores in the module file, hyphens in the clapnamewhen needed — e.g.copilot_vscode.rs→copilot-vscode). - Register it under
launch/mod.rs:- CLI targets first, then Apps & editors.
- Set
next_help_headingon the first variant of each group. - Keep
abouttext product-clear (… CLI,… IDE, …).
- Map to the correct provider key in auth / credentials (may already exist).
- Choose transport:
- CLI with base URL / headers → follow
claude.rs/codex.rs. - App that cannot be pointed at the gateway → thin wrapper calling
relay::run_for_agent("<canonical>")(seecursor.rs,copilot_vscode.rs).
- CLI with base URL / headers → follow
- If relay: accept only the canonical name from launch; put legacy spellings in
relay::canonicalize_targetas aliases, not as new public targets. Never alias a reserved bare CLI name to an app surface. - Update the root
README.mdsupported-setups table. edgee aliascovers both CLI and apps under one command:- CLI → PATH shims / shell aliases
- Apps → desktop wrappers (macOS
.app, Linux.desktop, Windows.lnk), only if the host app is already installed Register new app targets incommands/alias/desktop.rs(AppSpec+ detection).
Anti-patterns
- Exposing transport in the public UX (
edgee launch foo --relayas the main path for apps that only work via relay — prefer a dedicated target that always relays). - Using the IDE host name as the only public target when multiple products share that host (
vscodealone). - One subcommand with many surface flags (
--desktop,--vscode,--cli). - Forcing launch target name == provider key when multiple surfaces share billing/pipeline.
- Taking the bare product name for a non-CLI surface when a CLI is planned (
copilotfor VS Code).
copilot-desktop — local app sessions through the Copilot relay
macOS app 1.1.20 ships Copilot CLI 1.0.84-5. Launch
GitHub Copilot.app/Contents/MacOS/github directly so proxy env and
NODE_EXTRA_CA_CERTS reach that runtime. Native /responses traffic and a bash
tool round trip were verified on 2026-09-14. The released app explicitly ignores
COPILOT_CLI_PATH; BYOK replaces the user's subscription, so neither is used.
The bundled CLI's native model client also uses the dedicated, name-constrained
Copilot CA in the macOS system keychain.
This surface shares the established copilot key, settings and metering, as do
copilot-cli and copilot-vscode. No new backend slug or gateway strategy is needed
for this launcher. Its default port is 41600. App exit stops the relay; Ctrl-C closes
the app before stopping the relay. Quit an existing app first to avoid singleton handoff.
Remote/cloud runtimes do not inherit local proxy settings. Plugin delivery remains unverified for all four component kinds and is reported as unsupported. Windows/Linux app paths and transport remain unverified; this launch target currently supports macOS only.
intellij — GitHub Copilot in IntelliJ IDEA
Quit IntelliJ IDEA completely, then run edgee launch intellij /path/to/project.
The GitHub Copilot plugin must be installed and signed in. The launch shares
Copilot credentials, settings and usage attribution with the other Copilot targets.
It uses a separate local port (41700) so it can run alongside them.
The IDE executable inherits proxy environment variables and NODE_EXTRA_CA_CERTS,
which GitHub documents for Copilot.
An explicit IDE HTTP Proxy setting takes precedence; select No proxy in the
IDE to let Copilot use the launch environment. Certificate verification remains
enabled. No IDE configuration files or system trust stores are changed.
Standard macOS application bundles are detected in /Applications and
~/Applications; elsewhere the launcher must be on PATH (idea / idea.sh on
Linux, idea64.exe / idea.exe on Windows). For Toolbox or custom installations,
set EDGEE_INTELLIJ_BINARY to the executable path (on macOS, the app bundle's
Contents/MacOS/idea, not the .app directory).
edgee alias intellij installs a desktop wrapper when the IDE is detected.
Keep the launch command running for the session and quit the IDE before stopping
Edgee. A launcher can hand off to an existing IDE and exit, so Edgee keeps serving
until Ctrl-C. Live Copilot traffic still needs validation with an installed IDE;
this target is experimental until then. Other AI plugins and remote/cloud agent
sessions are outside this target's supported scope.