Skip to content

[CI only] upstream slice 4: program status - #23

Closed
LutzLange wants to merge 5 commits into
mainfrom
ci/s4-program-status
Closed

LutzLange wants to merge 5 commits into
mainfrom
ci/s4-program-status

Conversation

@LutzLange

Copy link
Copy Markdown
Owner

CI for upstream/s4-program-status plus a runner swap. Not for review.

LutzLange and others added 5 commits September 30, 2026 18:42
open::that waits for xdg-open to exit. In a Linux user session without a
display the launcher can hang on the portal call; the wait blocks the runtime
worker that holds the just-spawned callback server, so the login page never
answers and enrollment times out. open::that_detached returns immediately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of agentdesktop-dev#86. Adds an optional loopback proxy (`daemon.llmProxy.listen`, user
mode only) that forwards a client's model requests to the LLM gateway with
the device's gateway credential, for clients that cannot run an API-key
helper (GitHub Copilot CLI, VS Code Copilot Chat).

- Bound before the first apply; a failed bind keeps the daemon running and
  is reported in daemon-info (`llmProxy.bound`, `error`), also shown in the
  desktop app's daemon information panel.
- Fixed route prefix per client (`/copilot-cli`, `/vscode-copilot`,
  `/vscode-copilot-passthrough`), so the client ID the gateway sees comes
  from the route, not from the request.
- A per-device pairing value (`x-agentdesktop-pairing`) is required on every
  route; loopback Host check; OpenAI-style JSON errors.
- Request bodies are buffered (size cap) so a 401 is retried once with a
  fresh credential; controller credentials are cached briefly.
- `llmGateway.proxyUrl` for a proxy target that differs from `url`;
  `llmGateway.githubOAuth` for the upstream GitHub credential, taken from
  the client's own request (`source: request`) or from a GitHub App device
  flow (`deviceFlow`).

Co-authored-by: John Howard <john.howard@solo.io>
Co-authored-by: James McShane <james.mcshane@solo.io>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of agentdesktop-dev#86. Two programs that point Copilot at the local LLM proxy, user
mode only:

- `programs.copilot` writes the Copilot CLI's BYOK provider registry
  (`~/.copilot/providers.json`, or `$COPILOT_HOME` / `COPILOT_PROVIDERS_CONFIG`):
  providers `agentdesktop` (OpenAI-shaped) and `agentdesktop-anthropic` on the
  proxy's `/copilot-cli` route, with the pairing header; the user's own
  providers are kept. Discovery reports the CLI and its version from the npm
  manifest.
- `programs.vscode` with `copilotChat: ownModels` (default) writes
  `chatLanguageModels.json` for Copilot Chat's built-in Custom Endpoint
  provider on `/vscode-copilot`; the user's entries are kept.
- `copilotChat: githubModels` keeps GitHub's own models and the user's
  Copilot seat: the daemon sets `github.copilot.advanced.debug.overrideCapiUrl`
  in the user `settings.json` to the proxy's `/vscode-copilot-capi/<pairing>`
  route (pairing in the path, since VS Code cannot add a header), forwards to
  `llmGateway.proxyUrl` with the client's Copilot token moved aside, tunnels
  the Responses WebSocket for agent mode, forwards `_ping` without a
  credential, and keeps the override out of Settings Sync. `settings.json` is
  edited in place (JSONC): only the managed keys change, comments, key order
  and formatting stay, and removal restores the file byte for byte.

Managed files are written 0600 and carry a sidecar that records what the
daemon added, so removal takes out exactly that. A file the daemon cannot
parse is a conflict and left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each apply reports every managed program's outcome with a detail: applied,
unchanged, removed, conflict, inactive (the program uses the gateway but the
local proxy is not running), blocked (not applied because another program
conflicted) or failed. The daemon logs one line per program that was not
applied and sends the list with its ConfigStatus (additive proto fields
`programs`, `programs_reported`).

The controller stores the latest list per device (migration 0003,
`device_program_status`), returns it in `GET /api/v1/devices/{id}`, and the
device page shows a "Managed programs" card. Upgrade the controller first
(migration 0003 is one-way).

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

Copy link
Copy Markdown
Owner Author

Upstream PRs are open (agentdesktop-dev#133-agentdesktop-dev#138).

@LutzLange LutzLange closed this Sep 30, 2026
@LutzLange
LutzLange deleted the ci/s4-program-status branch September 30, 2026 17:00
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