You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add Pi discovery and managed gateway configuration - #109
Adds first-class support for the pi.dev coding-agent harness (@earendil-works/pi-coding-agent) so it shows up in local inventory and can be pointed at the LLM gateway.
Discovery
Binary:pi on PATH, plus Homebrew / ~/.local/bin candidates. The name pi is too generic to trust alone, so a candidate is accepted only after verifying the @earendil-works/pi-coding-agent package manifest. Windows npm CMD, PowerShell, and shell shims are checked against their sibling package and launch target without executing them. PowerShell-only installs are discovered from the standard npm location or custom locations on PATH, even when .ps1 is absent from PATHEXT; PowerShell PATH entries retain their order.
Version: npm package.json (no pi --version exec).
MCP: files pi-mcp-adapter actually loads. Globals are ~/.pi/agent/mcp.json, ~/.config/mcp/mcp.json, ~/.agents/mcp.json, and ~/.agents/mcp/mcp.json. Project files are the working directory's .mcp.json and .pi/mcp.json. Ancestor project files are included only when a user-global config sets settings.ancestorConfigRoots to an existing directory under the home that contains the working directory. Both .agents locations are supported by pi-mcp-adapter 2.34.0. PI_MCP_CONFIG_MODE=exclusive inventories only the Pi agent file. Host-specific Cursor/Claude files are not imported until the adapter copies them into a Pi-owned file. Args, env, and headers are omitted.
Skills:~/.pi/agent/skills, ~/.agents/skills, the working directory's .pi/skills, and .agents/skills from the working directory through the git repository root.
--user merges providers.agentdesktop into ~/.pi/agent/models.json (api: anthropic-messages, authHeader: true, apiKey: !<credential command> resolved at request time) and sets defaultProvider / defaultModel in settings.json. Other keys (theme, packages, extra providers) are preserved.
model is required when the gateway is used. An omitted models map creates that catalog entry. Model map keys determine catalog IDs, and generated gateway URLs take precedence over per-model endpoints using each model's API dialect.
Sandbox translation is not supported (same as Grok / OpenCode / Claude Desktop / Copilot CLI / VS Code).
daemon.pi.models / daemon.pi.settings in the local YAML configuration override the managed paths, matching the daemon startup configuration on main. ~ in PI_CODING_AGENT_DIR is expanded consistently for configuration, MCP, and skills.
Commented models.json files, including BOMs and trailing commas, are merged and rewritten as standard JSON while preserving user values. Other settings files retain strict JSON parsing.
On Unix, models.json is written owner-only (0600), and a looser mode is repaired on the next reconcile; cleanup keeps the file's current mode. Dry runs report the models.json action and path without its contents, since it may hold the user's own API keys.
Pi does not read /etc/pi, so programs.pi requires --user. It cannot be combined with Claude Desktop or Grok Build, which require system mode. Empty model IDs are rejected before models.json is written. Authenticated gateway configuration also rejects --once because credential helpers need a running daemon. In the system-mode Claude Desktop example, Pi is opt-in; remove Claude Desktop and use --user before enabling it.
Test plan
cargo test --locked -p agentdesktop-core -p agentdesktop-agent --lib — 412 passed (380 agent, 32 core), after merging main at a186749
cargo test --workspace — all unit tests pass; the container integration tests require Linux and pass in CI
Schema regenerated with cargo xtask schema and verified unchanged
Frontend pnpm check:lint, both frontend production builds, and Storybook interaction tests (99 passed)
CI on a186749: Test and lint, Windows agent tests, and Container all pass
Local Pi startup-path regression tests and CLI smoke: custom paths are honored, dry-run writes nothing, and generated model files retain private permissions
Built CLI smoke: system-mode Pi and authenticated Pi --once reject before writes; authenticated user dry-run previews without writing
Pi 0.85.1 runtime smoke: generated catalog loads, default model matches, per-model endpoints use the gateway, personal providers survive merge/repeat/removal
Regression fixtures cover Windows npm shims, unrelated-launcher rejection, custom directories, commented models, and configuration cleanup
Follow-ups
Official Pi mark if there is a canonical SVG
Wire crates/agent/tests/integration.rs once the container fixture exists
Nit (1): Update the walkthrough, prerequisites, and expected summary for Pi reconciliation.
examples/claude/claude-code.yaml
Adds Pi gateway configuration.
Moderate (1): Remove Pi from the system-mode example or provide a user-mode configuration/invocation.
crates/core/src/config.rs
Adds Pi config parsing and validation.
—
crates/agent/src/reconcile/mod.rs
Registers Pi reconciliation.
—
crates/agent/src/provider/README.md
Documents Pi provider support.
—
crates/agent/src/provider/pi/reconcile.rs
Merges Pi models and settings.
Moderate (2): Handle model IDs that differ from their map keys. Moderate (1): Support Pi-compatible comments in models.json. Critical (1): Prevent per-model baseUrl values from bypassing the managed gateway.
crates/agent/src/provider/pi/mod.rs
Defines Pi provider paths and behavior.
Critical (2): Reject unsupported system-mode management or implement a supported system path. Moderate (1): Expand ~ in PI_CODING_AGENT_DIR against the user home.
crates/agent/src/provider/pi/discovery.rs
Discovers Pi, MCP servers, and skills.
Moderate (1): Preserve each user’s default MCP root when an override is set. Moderate (1): Remove the unsupported ~/.agents/mcp/mcp.json path. Moderate (3): Resolve Windows pi.cmd npm shims or inspect the global package location. Moderate (1): Preserve each user’s default skills root alongside the override. Moderate (1): Normalize PI_CODING_AGENT_DIR, including ~ expansion. Moderate (1): Support Pi’s mcp-servers alias.
This function is documented as enumerating files that pi-mcp-adapter loads, but ~/.agents/mcp/mcp.json is not one of the adapter-owned paths listed in the PR contract. Scanning this extra file can show MCP servers in inventory that Pi will not actually load; remove it unless the adapter supports this path.
The documented Pi adapter paths include ~/.agents/mcp.json, but not ~/.agents/mcp/mcp.json. Scanning this extra file can surface MCP servers that Pi never loads, so the inventory is inaccurate; keep discovery limited to files the adapter actually reads.
Detect the pi.dev coding-agent harness (@earendil-works/pi-coding-agent),
inventory MCP servers and skills, and reconcile user-level models.json
and settings.json so Pi can use the LLM gateway with a request-time
credential helper.
Project MCP files stay in the working directory unless a user-global
adapter config opts into ancestorConfigRoots. Skill discovery keeps
.pi/skills in the working directory and stops .agents/skills at the
git root. Validation rejects Pi combined with Claude Desktop or Grok
Build, and rejects empty Pi model IDs before models.json is written.
…ness
Bring in the local LLM proxy, Copilot CLI and VS Code Copilot Chat
providers, per-program status, the opt-in reconcile tick, and inventory
refresh, and fit Pi into them.
- json_merge keeps main's MergeOptions (mode, keyed arrays, diff
redaction, looser-mode repair, removal keeping the file's mode) and
adds the JSONC format and replace_paths that Pi's models.json needs.
- Pi implements Provider::id and is listed by configured_programs, so it
gets a per-program status row like the other programs.
- Pi's models.json redacts dry-run diffs, like the other files that can
hold the user's API keys. Cleanup now keeps the file's current mode,
following main's json_merge removal rule.
- Reconciler::new, daemon startup paths, config validation, schemas,
READMEs, and the controller configuration list Pi next to the Copilot
CLI and VS Code.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E4vKY8hztcuF47Wc2hLnqA
json_merge keeps main's MergeOptions (mode, keyed arrays, diff redaction, looser-mode repair, removal keeping the file's mode) and adds only what Pi's models.json needs: the JSONC format and replace_paths. The Copilot CLI and VS Code options take the new fields from Default, so their behavior is unchanged.
Pi implements Provider::id and is listed in configured_programs, so it reports per-program status (pi_reports_applied_unchanged_removed_then_no_row). It needs no loopback proxy: its apiKey is a credential-helper command.
Pi's models.json now redacts dry-run diffs, like the other files that can hold the user's own API keys. Cleanup keeps the file's current mode, following main's removal rule; merges still write 0600 and repair a looser mode.
This branch has not been deployed
No deployments
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
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.
Summary
Adds first-class support for the pi.dev coding-agent harness (
@earendil-works/pi-coding-agent) so it shows up in local inventory and can be pointed at the LLM gateway.Discovery
pionPATH, plus Homebrew /~/.local/bincandidates. The namepiis too generic to trust alone, so a candidate is accepted only after verifying the@earendil-works/pi-coding-agentpackage manifest. Windows npm CMD, PowerShell, and shell shims are checked against their sibling package and launch target without executing them. PowerShell-only installs are discovered from the standard npm location or custom locations onPATH, even when.ps1is absent fromPATHEXT; PowerShellPATHentries retain their order.package.json(nopi --versionexec).pi-mcp-adapteractually loads. Globals are~/.pi/agent/mcp.json,~/.config/mcp/mcp.json,~/.agents/mcp.json, and~/.agents/mcp/mcp.json. Project files are the working directory's.mcp.jsonand.pi/mcp.json. Ancestor project files are included only when a user-global config setssettings.ancestorConfigRootsto an existing directory under the home that contains the working directory. Both.agentslocations are supported by pi-mcp-adapter 2.34.0.PI_MCP_CONFIG_MODE=exclusiveinventories only the Pi agent file. Host-specific Cursor/Claude files are not imported until the adapter copies them into a Pi-owned file. Args, env, and headers are omitted.~/.pi/agent/skills,~/.agents/skills, the working directory's.pi/skills, and.agents/skillsfrom the working directory through the git repository root.Managed configuration
--usermergesproviders.agentdesktopinto~/.pi/agent/models.json(api: anthropic-messages,authHeader: true,apiKey: !<credential command>resolved at request time) and setsdefaultProvider/defaultModelinsettings.json. Other keys (theme, packages, extra providers) are preserved.modelis required when the gateway is used. An omittedmodelsmap creates that catalog entry. Model map keys determine catalog IDs, and generated gateway URLs take precedence over per-model endpoints using each model's API dialect.daemon.pi.models/daemon.pi.settingsin the local YAML configuration override the managed paths, matching the daemon startup configuration onmain.~inPI_CODING_AGENT_DIRis expanded consistently for configuration, MCP, and skills.models.jsonfiles, including BOMs and trailing commas, are merged and rewritten as standard JSON while preserving user values. Other settings files retain strict JSON parsing.models.jsonis written owner-only (0600), and a looser mode is repaired on the next reconcile; cleanup keeps the file's current mode. Dry runs report themodels.jsonaction and path without its contents, since it may hold the user's own API keys.Pi does not read
/etc/pi, soprograms.pirequires--user. It cannot be combined with Claude Desktop or Grok Build, which require system mode. Empty model IDs are rejected beforemodels.jsonis written. Authenticated gateway configuration also rejects--oncebecause credential helpers need a running daemon. In the system-mode Claude Desktop example, Pi is opt-in; remove Claude Desktop and use--userbefore enabling it.Test plan
cargo test --locked -p agentdesktop-core -p agentdesktop-agent --lib— 412 passed (380 agent, 32 core), after mergingmainat a186749cargo test --workspace— all unit tests pass; the container integration tests require Linux and pass in CIcargo fmt --all --checkcargo clippy --locked --workspace --all-targets -- -D warningscargo xtask schemaand verified unchangedpnpm check:lint, both frontend production builds, and Storybook interaction tests (99 passed)--oncereject before writes; authenticated user dry-run previews without writingFollow-ups
crates/agent/tests/integration.rsonce the container fixture exists