Skip to content

feat: agent bridge daemon — drive Claude Code/Codex from XNet (0194, Phase 0) - #148

Merged
crs48 merged 3 commits into
mainfrom
feat/agent-bridge-0194
Jun 17, 2026
Merged

feat: agent bridge daemon — drive Claude Code/Codex from XNet (0194, Phase 0)#148
crs48 merged 3 commits into
mainfrom
feat/agent-bridge-0194

Conversation

@crs48

@crs48 crs48 commented Jun 17, 2026

Copy link
Copy Markdown
Owner

What & why

Exploration 0194, Phase 0. XNet's chat panel already probes for a "Local bridge" daemon at http://127.0.0.1:31416 (the top-preference connector tier) — but nothing served it. This adds that missing daemon, so the panel can drive the user's own Claude Code / Codex CLI, leveraging their subscription. The daemon spawns the user's installed CLI and never sees an auth token (the ToS-safe BYO-agent model).

Changes

@xnetjs/devkit

  • ChatAgent port + cliChatAgent (spawns claude -p / codex exec, returns the reply) + fakeChatAgent; flattenChat.
  • createBridgeServer — a hardened loopback HTTP daemon:
    • GET /healthbridgeHealth() so the panel's bridge tier detects it.
    • POST /v1/chat/completionsOpenAI-compatible, streaming (SSE, which the panel's provider requests) and one-shot, backed by a ChatAgent.
    • Loopback-only bind, OPTIONS preflight, Origin allowlist (loopback + configured; never wildcard), Access-Control-Allow-Private-Network — mirrors the MCP HTTP transport's hardening.

Because the existing bridge tier already maps to openai-compatible, this works with zero panel changes — the facade is the "quick win" from the exploration.

@xnetjs/cli

  • xnet bridge serve [--agent claude|codex] [--port] [--allow-origin] [--cwd] — builds a cliChatAgent and starts the daemon. Makes the bridge work on the web deployment (browser → local daemon) as well as Electron.

apps/electron

  • agent-bridge-manager starts the daemon on boot (fire-and-forget) but only advertises it when the agent CLI is actually runnable (a --version probe), so the panel never shows an "available" bridge that errors on first message. Stops on quit; status/start/stop IPC + window.xnetAgentBridge preload.

Tests / validation

  • devkit 44 (chat-agent 6, bridge-server 7 — real ephemeral server, SSE, origin/PNA gates, non-loopback refusal, agent→502) and CLI 35 (bridge health + injected-agent chat), green under the repo's vitest projects.
  • typecheck (devkit + cli), electron main tsc (only a pre-existing unrelated error in social-import-ipc.ts), eslint --max-warnings 0, prettier --check: clean.
  • Not exercised in CI: a packaged Electron build with a real claude installed. By design, no subscription token is read.

Deferred (in the exploration)

ACP transport + agent registry ("any agent": Gemini/OpenCode-Kimi), mapping agent permission requests to XNet's approval flow, and wiring XNet's MCP tool surface into the spawned agent so it edits the workspace (pages/db/canvas) and authors plugins (Phases 1–4).

🤖 Generated with Claude Code

xNet Test and others added 3 commits June 17, 2026 11:50
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Serves the loopback endpoint XNet's chat panel already probes at :31416 (the
'Local bridge' connector tier, preference #1) — the missing 'thin shell' that
makes Claude Code / Codex / any agent usable from XNet's UI, leveraging the
user's own subscription (the daemon spawns the user's CLI; it never sees a token).

@xnetjs/devkit:
- ChatAgent port + cliChatAgent (spawns claude -p / codex exec, returns reply)
  + fakeChatAgent; flattenChat. ToS-safe BYO-agent model.
- createBridgeServer: hardened loopback HTTP daemon serving GET /health
  (bridgeHealth, so the panel detects it) and POST /v1/chat/completions —
  OpenAI-compatible, streaming (SSE, which the panel's provider requests) and
  one-shot. Loopback-only bind, OPTIONS preflight, Origin allowlist (loopback +
  configured; never wildcard), Access-Control-Allow-Private-Network. Mirrors the
  MCP HTTP transport's hardening.

@xnetjs/cli:
-
  builds a cliChatAgent and starts the daemon. Makes the bridge tier work on the
  web deployment (browser → local daemon) as well as Electron.

apps/electron:
- agent-bridge-manager starts the daemon on boot (fire-and-forget), but only
  advertises it when the agent CLI is actually runnable (a --version probe), so
  the panel never shows an 'available' bridge that errors on first message.
  Stops on quit; status/start/stop IPC + preload (window.xnetAgentBridge).

Tests: devkit 44 (chat-agent 6, bridge-server 7 incl real ephemeral server +
SSE + origin/PNA gates), cli 35 (bridge health + injected-agent chat). devkit
+ cli typecheck, electron main tsc, eslint --max-warnings 0, prettier clean.

Deferred (in the exploration): ACP transport + agent registry (any agent),
mapping permissions to the approval flow, and wiring the MCP tool surface into
the spawned agent so it edits the workspace (Phase 2-4).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@crs48
crs48 temporarily deployed to pr-148 June 17, 2026 19:48 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #148.

github-actions Bot added a commit that referenced this pull request Jun 17, 2026
@crs48
crs48 merged commit d658d45 into main Jun 17, 2026
8 of 10 checks passed
@crs48
crs48 deleted the feat/agent-bridge-0194 branch June 17, 2026 19:53
github-actions Bot added a commit that referenced this pull request Jun 17, 2026
}

/** Start the bridge if the chosen agent CLI is installed; otherwise record why. */
export async function startAgentBridge(
crs48 added a commit that referenced this pull request Jun 17, 2026
## What & why

Exploration
[0194](docs/explorations/0194_[_]_AGENT_BRIDGE_CLAUDE_CODE_CODEX_AND_ANY_AGENT_IN_XNET.md),
Phase 1 (real). Phase 0 ([#148](#148))
made the bridge **chat** through the user's Claude Code/Codex CLI. This
makes it **act on the workspace**: the spawned agent is handed XNet's
MCP tool server, so it can search/read and create/update pages,
databases, and canvases via the `xnet_*` tools.

## Changes

**`@xnetjs/devkit`** — `agent-launch.ts`:
- `buildAgentArgs(agent, { mcpConfigPath, allowedTools })` maps a known
agent CLI to its headless argv. Claude Code gets `--mcp-config` +
`--allowedTools "mcp__xnet__*"` (the documented way to auto-approve MCP
tools in print mode; `acceptEdits` does not cover MCP). Codex uses
`exec` (MCP via its global config).
- `mcpConfigFor(serverSpec)` builds the `mcpServers` JSON. Pure +
tested.

**`@xnetjs/cli`** — `xnet bridge serve --mcp [--mcp-api-url]` writes a
**self-referential** MCP config (`node <this-cli> mcp serve --api-url
:31415`, so it resolves without the `xnet` binary on PATH) and launches
the agent with workspace tools.

**`apps/electron`** — `agent-bridge-manager` wires MCP opt-in via env
(`XNET_BRIDGE_MCP` + `XNET_BRIDGE_MCP_CLI`; default chat-only) so a
packaged app can enable workspace tools once the CLI entry path is
known.

**Safety:** `xnet_*` writes flow through the existing server-side
`McpWriteGuardrail` — low/medium-risk auto-apply (creating pages/rows),
high-risk/outward-facing require `confirm:true`. The user's own loopback
agent; XNet never sees an auth token.

## Tests / validation

- **devkit 50** (agent-launch 6: claude with/without MCP, custom
allowedTools, codex, mcpConfigFor) + **CLI 36** (bridge MCP-args
wiring), green under the repo's vitest projects.
- `typecheck` (devkit + cli), electron main `tsc` (only the pre-existing
unrelated `social-import-ipc.ts` error), `eslint --max-warnings 0`,
`prettier --check`: clean.
- Not in CI: end-to-end with a real `claude` + `xnet` CLI editing a live
workspace.

## Deferred (in the exploration)

ACP transport + agent registry ("any agent": Gemini/OpenCode-Kimi);
surfacing the approval flow in the panel UI; auto-resolving the CLI path
so Electron MCP is on by default; plugin authoring via `runAgentTask`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
crs48 added a commit that referenced this pull request Jun 17, 2026
## What & why

Exploration
[0194](docs/explorations/0194_[_]_AGENT_BRIDGE_CLAUDE_CODE_CODEX_AND_ANY_AGENT_IN_XNET.md),
Phase 4 (code/plugins). The bridge lets an agent edit your **workspace**
(PRs #148, #152). This adds the other axis the prompt asked for —
**authoring/editing code & plugins** — by exposing the proven
`@xnetjs/devkit` dev-loop as a command.

`xnet code "<intent>"` isolates in a git worktree → runs your own coding
agent (Claude Code/Codex/aider) → runs the validation gate (typecheck →
lint → test → fallow) → **checkpoints on pass / rolls back on fail** →
optionally opens a PR.

## Changes

- **`@xnetjs/cli`** — new `code` command. Thin wiring over devkit
(`runAgentTask` + `defaultXnetGate` + `cliAgentRunner` + `Git` +
`openPullRequest`), with pure, tested helpers:
- `resolveCodeRunConfig(prompt, options, repoRoot, now?)` — maps CLI
options → dev-loop config (id/branch/base/worktree/gate/keepWorktree);
clock injected for deterministic ids.
- `summarizeAgentTaskResult(result)` — result → one-liner (passed /
no-changes / gate-failed-at-X / failed).
- Flags: `--agent`, `--id`, `--branch`, `--base`, `--worktree`, `--pr`,
`--keep`, `--repo`.

## Tests / validation

- **CLI 43** (code 7: config derivation, explicit overrides, keep-on-PR,
all four summary states). The heavy worktree→gate→checkpoint loop is
already covered by devkit's real-temp-git e2e.
- `typecheck`, `eslint --max-warnings 0`, `prettier --check`: clean. No
new deps (cli already depends on `@xnetjs/devkit`).
- Not in CI: end-to-end with a live coding agent.

## Deferred

Wiring "create/edit a plugin" into the in-app UI (e.g. the bridge
daemon's `/run` endpoint over devkit `handleBridgeRun`) + combining with
the plugin scaffolder; and the ACP transport / in-panel approvals from
earlier phases.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
crs48 added a commit that referenced this pull request Jun 18, 2026
…193/0194) (#201)

The `changelog-section` required check was only added in #164, so the
0192/0193/0194 feature batch merged before it never got changelog
entries. This backfills the 12 user-facing features that were missing,
each dated to its merge day with its PR number and contributors:

| PR | Entry |
|----|-------|
| #138 | A safer foundation for plugins |
| #145 | One trust model across plugins and Labs |
| #146 | Reliability you can see for managed hubs |
| #148 | Drive your own coding agent from xNet |
| #149 | AI that can act on your workspace |
| #150 | Your Labs become AI tools |
| #152 | Your agent can use your workspace |
| #154 | AI edits, right inside the editor |
| #155 | An agentic dev loop in your terminal |
| #158 | Review AI edits before they apply |
| #159 | Kick off agentic code tasks from xNet |
| #162 | Plugins run on the Labs runtime |

Skipped: PRs already covered by umbrella entries (#142 plugin ecosystem,
#144 extensibility fabric, #147 automated changelog, #163 agent panel,
#180 changelog gallery), internal-only changes (#139 schema authz — zero
user-facing effect), and meta/test/docs PRs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

2 participants