Skip to content

feat(cloud-coding-agents): Eliza Cloud as provider for CLI coding agents#1757

Merged
HaruHunab1320 merged 9 commits intodevelopfrom
feat/eliza-cloud-cli-provider
Apr 8, 2026
Merged

feat(cloud-coding-agents): Eliza Cloud as provider for CLI coding agents#1757
HaruHunab1320 merged 9 commits intodevelopfrom
feat/eliza-cloud-cli-provider

Conversation

@HaruHunab1320
Copy link
Copy Markdown
Contributor

Summary

Adds Eliza Cloud as an LLM provider for the CLI coding agents (Claude Code, Codex, Aider) and ships the supporting milady-side plumbing. Eliza Cloud does not proxy Gemini, so cloud mode leaves Gemini's auth state unchanged.

Paired with elizaos-plugins/plugin-agent-orchestrator#27 (already merged + published as @elizaos/plugin-agent-orchestrator@0.6.1), which ships the plugin-side cloud provider integration and three reliability fixes.

Important caveat: Codex-through-Eliza-Cloud is still blocked on the cloud-eliza side pending elizaOS/cloud#427 (native Responses-API passthrough) + #428 (stream-teed credit reconciliation). This PR prepares milady to be ready the moment those cloud PRs deploy — merging this in the meantime doesn't change any currently-working flow.

Auth readiness

  • packages/agent/src/runtime/agent-orchestrator-compat.ts — added readMiladyEnvKey and readMiladyCloudApiKey helpers, and a cloudReady branch that treats Claude / Codex as fully auth-ready when PARALLAX_LLM_PROVIDER=cloud and a cloud.apiKey is paired in milady.json. Plumbed through the framework availability surface so the settings UI reflects it.

  • packages/agent/src/auth/credentials.ts — extended the Claude Code OAuth credential reader to also accept:

    • the .credentials.json blob format
    • the macOS Keychain entry "Claude Code-credentials" (current macOS installs)

    Kept the TOS-respecting policy of not exporting the Claude subscription token as ANTHROPIC_API_KEY to the main runtime — the token is still only usable via the Claude Code CLI spawned by the task-agent orchestrator.

API routes

  • packages/agent/src/api/coding-agent-bridge.ts — surfaces adapter auth status through the framework list, and adds a new POST /api/coding-agents/auth/:agent route that triggers the CLI auth flow via coding-agent-adapters.

  • packages/agent/src/api/server.ts — registers the trigger-auth route in the fallback handler alongside the existing agent list.

Settings UI

  • packages/app-core/src/components/coding/CodingAgentSettingsSection.tsx — rewritten to surface the Eliza Cloud provider option, let the user pair a cloud API key, and reflect per-CLI auth readiness under both subscription-mode and cloud-mode. +439/−91 LOC, drives the settings surface for all CLI agents.

  • packages/app-core/src/api/client-types-cloud.ts — client types for the new cloud auth state fields.

xterm theme

  • packages/app-core/src/components/coding/PtyTerminalPane.tsx — added a full 16-color ANSI palette (Tokyo Night Storm) so Codex's dim brightBlack commentary is readable against the dark terminal background. Previously the default xterm palette left Codex's reasoning text almost invisible.

Plumbing

  • @elizaos/plugin-agent-orchestrator bumped to 0.6.1 in both the root and packages/agent/package.json. The plugin at that version ships the matching cloud provider integration + reliability fixes (watchdog isSessionLoading gate, validator filesystem evidence, 2nd-person idle nudge prompt, Codex WS-disable via custom provider). See plugin PR Fix/plugins page scroll #27.

  • Submodule pointer for plugins/plugin-agent-orchestrator bumped to ad3bf3c — the alpha tip with the workspace-dep regression fix on top of Fix/plugins page scroll #27.

  • .gitignore — excludes scripts/codex-sniff.ts, a local sniffing proxy used to debug the Codex ↔ Vercel AI Gateway request shape during this feature's development. Useful dev tool, not product code.

Test plan

  • bun run verify:typecheck11 pre-existing errors, same count as pristine develop. Zero net-new errors.
  • bun run verify:lint (biome) — pre-existing ~44 errors / ~46 warnings in the touched files on develop, reduced to ~37 / ~44 on this branch via biome check --write auto-fixes (formatting only, no behavior changes).
  • Plugin resolves via submodule to 0.6.1 locally; npm consumers will pull the published 0.6.1 once available.
  • Full milady build + manual settings UI verification (leaving to reviewer env).

Stacked dependencies

Dependency Status
@elizaos/plugin-agent-orchestrator@0.6.1 ✅ Merged (elizaos-plugins/plugin-agent-orchestrator#27)
pty-manager@1.11.0 ✅ Published to npm
coding-agent-adapters@0.16.3 ✅ Published to npm
elizaOS/cloud#427 ⏳ Open — required for Codex-through-cloud to actually work
elizaOS/cloud#428 ⏳ Open — stacked on #427, stream-teed credit reconciliation

Followups (not in this PR)

🤖 Generated with Claude Code

Adds Eliza Cloud as an LLM provider for the CLI coding agents
(Claude Code, Codex, Aider) and ships the supporting milady-side
plumbing. Eliza Cloud does NOT proxy Gemini, so cloud mode leaves
Gemini's auth state unchanged.

## Auth readiness

- `packages/agent/src/runtime/agent-orchestrator-compat.ts` — added
  `readMiladyEnvKey` and `readMiladyCloudApiKey` helpers, and a
  `cloudReady` branch that treats Claude / Codex as fully auth-ready
  when `PARALLAX_LLM_PROVIDER=cloud` and a `cloud.apiKey` is paired
  in `milady.json`. Plumbed through the framework availability
  surface so the settings UI reflects it.

- `packages/agent/src/auth/credentials.ts` — extended the Claude Code
  OAuth credential reader to also accept the `.credentials.json`
  blob format and the macOS Keychain entry `"Claude Code-credentials"`
  (current macOS installs). Kept the TOS-respecting policy of
  NOT exporting the Claude subscription token as `ANTHROPIC_API_KEY`
  to the main runtime — the token is still only usable via the
  Claude Code CLI spawned by the task-agent orchestrator.

## API routes

- `packages/agent/src/api/coding-agent-bridge.ts` — surfaces adapter
  `auth` status through the framework list, and adds a new
  `POST /api/coding-agents/auth/:agent` route that triggers the CLI
  auth flow via `coding-agent-adapters`.

- `packages/agent/src/api/server.ts` — registers the trigger-auth
  route in the fallback handler alongside the existing agent list.

## Settings UI

- `packages/app-core/src/components/coding/CodingAgentSettingsSection.tsx`
  — rewritten to surface the Eliza Cloud provider option, let the
  user pair a cloud API key, and reflect per-CLI auth readiness
  under both subscription-mode and cloud-mode.

- `packages/app-core/src/api/client-types-cloud.ts` — client types
  for the new cloud auth state fields.

## xterm theme

- `packages/app-core/src/components/coding/PtyTerminalPane.tsx` —
  added a full 16-color ANSI palette (Tokyo Night Storm) so Codex's
  dim brightBlack commentary is readable against the dark terminal
  background. Previously the default xterm palette left Codex's
  reasoning text almost invisible.

## Plumbing

- `@elizaos/plugin-agent-orchestrator` bumped to `0.6.1` in both
  the root and `packages/agent/package.json`. The plugin ships the
  matching cloud provider integration + reliability fixes
  (watchdog `isSessionLoading` gate, validator filesystem evidence,
  2nd-person idle nudge prompt, Codex WS-disable via custom
  provider). See plugin PR #27 for details.

- Submodule pointer for `plugins/plugin-agent-orchestrator` bumped
  to `ad3bf3c` — the alpha tip with the workspace-dep regression
  fix on top of #27.

- `.gitignore` — excludes `scripts/codex-sniff.ts`, the local
  sniffing proxy used to debug the Codex ↔ Vercel AI Gateway
  request shape. Useful developer tool, not product code.

## Known pre-existing issues unchanged by this PR

- Typecheck: 11 pre-existing `tsc --noEmit` errors on develop,
  same 11 on this branch. No net-new errors.
- Biome: pre-existing ~44 errors / ~46 warnings in the touched
  `packages/agent/src/**` files on develop, reduced to ~37 / ~44
  on this branch via `biome check --write` auto-fixes to formatting
  only — no behavior changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added the build label Apr 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The review is complete. Here's the summary:


PR #1757 — feat(cloud-coding-agents): Eliza Cloud as provider for CLI coding agents

Decision: REQUEST CHANGES

Classification: Feature — adds Eliza Cloud as an LLM provider for CLI coding agents (Claude Code, Codex, Aider), extends OAuth credential reading, and rewrites the coding agent settings UI. Consistent with author's claim.

Scope: Needs deep review (touches runtime auth, credentials, API routes, and UI — 726 additions, new contributor).

Universal invariants: All intact.


Critical bug (blocks merge):

importClaudeCodeOAuthToken() was promoted from sync to async (Promise<string | null>), but getSubscriptionStatus() — a sync export called by GET /api/subscription/status — still calls it without await:

const importedClaudeAuth =
  provider === "anthropic-subscription"
    ? (importClaudeCodeOAuthToken() ?? readConfiguredAnthropicSetupToken())  // Promise, never null
    : null;

A Promise object is always truthy. After this PR, every user will appear to have a valid Anthropic subscription configured, regardless of reality. The provider switcher UI and subscription status endpoint are both affected.


Secondary required changes:

  1. _CLOUD_API_KEY data leak — the synthetic key loaded from config.cloud.apiKey gets written back into config.env._CLOUD_API_KEY on every auto-save keystroke. Filter _-prefixed keys from envPatch.

  2. Memory leaksetInterval in handleAuth (polling for auth completion) has no unmount cleanup. Continues firing network requests after the settings panel closes.

  3. No tests — zero regression tests added for the auth behavior or getSubscriptionStatus async call path.


Noted (non-blocking): Codex-through-cloud is correctly flagged as blocked upstream on elizaOS/cloud#427+#428. The UI is wired but won't function until those cloud PRs deploy — doesn't break currently-working flows.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) labels Apr 8, 2026
… status, plug settings leaks

- getSubscriptionStatus() stays sync and reads the Claude Code OAuth
  blob directly. Fixes the Promise-truthy regression where every user
  appeared to have a valid Anthropic subscription configured.
- CodingAgentSettingsSection: filter _-prefixed synthetic keys from
  the auto-save envPatch so _CLOUD_API_KEY no longer leaks from
  config.cloud.apiKey into config.env on every keystroke.
- CodingAgentSettingsSection: track the auth-completion poll in a ref
  and clear it on unmount / new auth flow to stop the setInterval
  network-request leak after the settings panel closes.
- packages/agent: declare missing @miladyai/coding-agent-adapters
  workspace dependency.
- deploy/cloud-agent-template: pin Eliza dependency versions to
  satisfy the release contract check.
- Add regression tests for getSubscriptionStatus covering the sync
  signature, missing-blob, fresh-blob, expired-blob, setup-token
  fallback, and codex negative cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The review is complete. Here is the full verdict — please post it to the PR when ready:


Preliminary — awaiting Greptile deep review. A final weighted verdict will be posted once Greptile responds.


1. Classification (derived): feature — consistent with author's claim. Touches auth credential handling, new API endpoint, new third-party dependency, settings UI rewrite (+439/−91 LOC), plugin version bumps, and an unexplained deploy/cloud-agent-template version pin.

2. Rubric (derived): New dependency vetting, auth/credential handling correctness, API endpoint security, React state management correctness, and soundness of the partially-blocked Codex-through-cloud path.

3. Scope verdict: needs deep review

4. Universal invariants: all intact — NODE_PATH in all three sites, patch-deps intact, Electrobun startup guards intact, milady namespace preserved, no hardcoded port numbers, no top-level plugin imports, no access control file touches.

5. Judgment:

  • Needed? — OK. Cloud provider option and CLI auth flow surface are load-bearing roadmap work.
  • Better than existing? — CONCERN: Auto-save replaces a deliberate save button with per-keystroke writes. The old SaveFooter pattern was intentional friction; partial state is now always persisted.
  • Duplication? — CONCERN: POST /api/coding-agents/auth/:agent is added identically in both the exported handleCodingAgentsFallback in coding-agent-bridge.ts and the private copy in server.ts (line 4224). Two identical handlers for the same route will inevitably diverge.
  • Blast radius covered? — CONCERN: deploy/cloud-agent-template/package.json pins workspace:* to specific alpha versions — unexplained, absent from PR summary, could break cloud deploys.
  • Logic sound? — CONCERN: three issues:
    1. React anti-pattern. setPref calls void client.updateConfig() inside setPrefs((prev) => { return next }). State updaters must be pure. In React Strict Mode this fires the network call twice per keystroke. API key fields now trigger 40+ partial-key writes per key entered; if any write fails mid-flight, config is left with a partial key.
    2. readClaudeCodeOAuthBlob() called twice per getSubscriptionStatus(). Once for importedClaudeAuth, once for blobExpiresAt. On macOS this is two execSync Keychain calls per poll. Call it once and destructure.
    3. Codex falsely marked auth-ready. PR description: "Codex-through-Eliza-Cloud is still blocked pending cloud#427." But codexReady = cloudReady || ... marks Codex ready whenever cloud is selected. Users will see Codex as auth-ready, start a session, and hit a runtime failure with no explanation.
  • Complexity appropriate? — CONCERN: Removing the explicit Default Agent Type selector means every tab click silently resets PARALLAX_DEFAULT_AGENT_TYPE. Users inspecting agent settings inadvertently change their default.
  • Tested meaningfully? — CONCERN: The getSubscriptionStatus() regression test is solid. Zero tests exist for readMiladyEnvKey, readMiladyCloudApiKey, cloudReady logic, the new auth endpoint, or auto-save behaviour.
  • Matches conventions? — CONCERN: SettingsControls.MutedText used with hardcoded className overrides (text-green-500, text-amber-500) bypasses the design token layer.
  • Plausible breakage mode identified? — User selects Eliza Cloud, has a cloud API key, Codex shows as ready, user starts a Codex task → runtime failure because cloud#427 has not shipped. No recovery path, no explanation in UI.

6. PR-type-specific checks:

  • coding-agent-adapters@0.16.3 — new package, handles OAuth flows and spawns CLIs: CONCERN (see Security)
  • pty-manager bump 1.10.2 → 1.11.0: CONCERN — no changelog in PR summary, could affect all PTY sessions
  • plugin-agent-orchestrator submodule to 0.6.1: OK — paired plugin PR confirmed merged
  • deploy/cloud-agent-template version pinning: CONCERN — unrelated, unjustified
  • Auth poll unmount cleanup via authPollRef: OK
  • import type http changes: OK

7. Security: concerns

  • POST /api/coding-agents/auth/:agent: (\w+) regex prevents path traversal. However, the full adapter.triggerAuth() response is forwarded to the browser without field filtering. If triggerAuth() returns an OAuth access token or device secret in an unexpected field, it reaches the client. The auth field on the framework list (auth?: Record<string, unknown>) is similarly untyped and passed from the plugin wholesale.
  • coding-agent-adapters@0.16.3 is a new third-party package not previously in the dependency tree, dynamically imported to trigger OAuth login flows. Requires supply chain review: publisher identity, whether it has a postinstall script, what triggerAuth() actually spawns.
  • Keystroke-level writes of API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY) to milady.json plain JSON: partial keys are persisted to disk during entry — non-zero credential-exposure window on shared/audited machines.

8. Decision: REQUEST CHANGES

Blocking items before merge:

  1. Move updateConfig call out of the state updater — use useEffect([prefs]) with a debounce, or call it directly after setPrefs.
  2. Deduplicate the auth route handler between coding-agent-bridge.ts and server.ts.
  3. Gate Codex out of cloudReady until cloud#427 ships, or show a disabled-with-tooltip state in the UI for Codex in cloud mode.
  4. Call readClaudeCodeOAuthBlob() once in getSubscriptionStatus() and reuse the result for both importedClaudeAuth and blobExpiresAt.
  5. Justify or revert deploy/cloud-agent-template/package.json version pinning.
  6. Supply-chain confirm coding-agent-adapters is org-owned and has no postinstall hook.

@greptileai please perform a deep review — this PR was flagged as needing deep analysis by agent-review.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
- CodingAgentSettingsSection: move updateConfig out of the setPrefs
  state updater into a debounced useEffect (400ms). React state
  updaters must be pure; the old path fired twice per keystroke in
  Strict Mode and persisted 40+ partial-key snapshots while a user
  typed an API key. The debounce coalesces rapid edits into a single
  POST so a mid-flight failure can no longer leave milady.json with
  a partial credential.
- coding-agent-bridge: drop the unused duplicate of the
  POST /api/coding-agents/auth/:agent handler. The canonical copy
  lives in server.ts's private handleCodingAgentsFallback — the
  bridge export was never wired in, so keeping both would silently
  drift.
- agent-orchestrator-compat: stop treating Codex as auth-ready under
  cloudReady. elizaOS/cloud#427 (responses-stream reconciliation)
  has not deployed, so Codex-through-cloud would fail at runtime
  with no explanation. Restore once cloud#427/#428 ship.
- credentials: call readClaudeCodeOAuthBlob() once per provider row
  and destructure, instead of hitting it twice (the second call
  shelled out to `security` on macOS on every status poll).

deploy/cloud-agent-template/package.json pin is left in place: the
release contract check requires exact versions there (the template
is published as a standalone deploy artifact, not a workspace
member, so `workspace:*` won't resolve against any registry).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 8, 2026

Greptile Summary

This PR adds Eliza Cloud as an LLM provider for CLI coding agents (Claude Code, Codex, Aider), wires up a new POST /api/coding-agents/auth/:agent route with a response sanitizer, extends the Claude Code OAuth credential reader to cover both the .credentials.json file and the macOS Keychain, and rebuilds CodingAgentSettingsSection to surface the cloud provider option and per-CLI auth readiness.

The two blockers flagged in the previous review round (HTTP-200-on-error on the auth route and the TOCTOU double-read of the Claude blob in getSubscriptionStatus) have been addressed. The new sanitizeAuthResult and normalizePreflightAuth modules are well-tested and correctly whitelist fields / reject javascript: URLs.

Key issues remaining:

  • P1 – stuck loading state in cloud mode with Gemini-only install (CodingAgentSettingsSection.tsx): when isCloud=true and Gemini is the only installed CLI, availableAgents becomes empty while installedAgents.length > 0, so the "no supported CLIs" guard at line 521 never fires, activeTab stays null, and the component renders "Loading Coding Agent" forever.
  • P2 – silent auth failure in the UI: handleAuth discards non-ok responses without setting any error state, leaving the user staring at a re-enabled "Authenticate" button with no explanation.
  • P2 – redundant milady.json reads in computeFrameworkState: five independent readJsonFile(resolveMiladyConfigPath()) calls per invocation. The 15 s cache bounds frequency but a single read at the top of the function would be cleaner.

Greptile verdict: REQUEST CHANGES

Confidence Score: 3/5

Not safe to merge as-is: the cloud-mode + Gemini-only scenario produces an unrecoverable loading state in the settings UI.

The two previously-flagged blockers (HTTP-200-on-error, double blob read) are fixed and the new sanitizer/normalizer modules are correct. However, a new P1 regression exists: when PARALLAX_LLM_PROVIDER=cloud is selected and Gemini is the only installed CLI, availableAgents becomes empty while installedAgents.length > 0, bypassing the "no supported CLIs" guard and leaving the component stuck on the loading spinner indefinitely. The auth error silence (P2) and redundant file reads (P2) are follow-up quality items. One targeted fix to the availableAgents / "no CLIs" guard brings this to merge-ready.

packages/app-core/src/components/coding/CodingAgentSettingsSection.tsx — stuck loading state (P1) and silent auth failure (P2)

Vulnerabilities

  • sanitizeAuthResult and normalizePreflightAuth correctly whitelist fields and reject javascript: / data: / file: URLs before forwarding adapter responses to the browser — good defense-in-depth at the HTTP boundary.
  • readClaudeCodeOAuthBlob shells out to security find-generic-password with a 3 s timeout and literal arguments, which avoids shell injection; the keychain entry name is a string literal.
  • The extractOauthAccessToken recursive traversal in agent-orchestrator-compat.ts has no explicit depth cap, but the inputs are local user-controlled credential files, so no remote exploitation path exists.
  • PARALLAX_LLM_PROVIDER=cloud with a paired cloud.apiKey marks Claude as auth-ready without forwarding any credentials to the environment; the TOS-respecting no-ANTHROPIC_API_KEY policy is preserved.
  • No new secrets are logged or persisted outside existing patterns.

Important Files Changed

Filename Overview
packages/app-core/src/components/coding/CodingAgentSettingsSection.tsx Major rewrite (+439/−91) adding cloud provider option, per-CLI auth readiness indicators, and debounced auto-save; contains a P1 stuck-loading bug when cloud mode is active and only Gemini CLI is installed, and a P2 silent-failure on auth error path.
packages/agent/src/runtime/agent-orchestrator-compat.ts Adds readMiladyEnvKey and readMiladyCloudApiKey helpers and wires cloudReady into Claude's auth-readiness check; logic is correct but introduces three additional synchronous milady.json reads per computeFrameworkState call (P2 efficiency concern).
packages/agent/src/auth/credentials.ts Extends readClaudeCodeOAuthBlob to cover both .credentials.json and macOS Keychain; the previously flagged double-read TOCTOU is fixed (single claudeBlob capture per getSubscriptionStatus map iteration).
packages/agent/src/api/server.ts Registers POST /api/coding-agents/auth/:agent in the fallback handler with a 15 s timeout and correct 4xx/504 status codes; the previously flagged HTTP-200-on-error bug is fixed.
packages/agent/src/api/coding-agents-auth-sanitize.ts New module that whitelists four fields and rejects non-http(s) URLs from adapter triggerAuth() responses; well-tested and correctly prevents javascript: / file: URL injection.
packages/agent/src/api/coding-agents-preflight-normalize.ts Pins the auth field shape from the adapter preflight at the HTTP boundary; correctly coerces unknown statuses to "unknown" and drops unexpected fields.
packages/app-core/src/components/coding/PtyTerminalPane.tsx Adds full 16-color ANSI palette (Tokyo Night Storm) to fix illegible brightBlack commentary rows in Codex; straightforward and low-risk.
packages/app-core/src/api/client-types-cloud.ts No significant changes visible in this file from the diff context; types appear consistent with the new auth fields surfaced by the bridge.

Sequence Diagram

sequenceDiagram
    participant UI as CodingAgentSettingsSection
    participant API as API Server (server.ts)
    participant Adapter as coding-agent-adapters
    participant Sanitizer as coding-agents-auth-sanitize
    participant Preflight as /api/coding-agents/preflight
    participant Compat as agent-orchestrator-compat
    participant Config as milady.json

    UI->>API: POST /api/coding-agents/auth/:agent
    API->>Adapter: createAdapter(agentType)
    API->>Adapter: adapter.triggerAuth() [15s timeout]
    Adapter-->>API: { launched, url, deviceCode, instructions }
    API->>Sanitizer: sanitizeAuthResult(triggered)
    Note over Sanitizer: Whitelist 4 fields<br/>Reject non-http(s) URLs
    Sanitizer-->>API: SanitizedAuthResult
    API-->>UI: 200 { launched, url, deviceCode, instructions }
    UI->>UI: setInterval poll every 3s (max 2min)

    loop Poll for auth completion
        UI->>Preflight: GET /api/coding-agents/preflight
        Preflight->>Compat: computeFrameworkState()
        Compat->>Config: readJsonFile(milady.json) x5
        Note over Compat: readConfiguredSubscriptionProvider<br/>readMiladyEnvKey(PARALLAX_LLM_PROVIDER)<br/>readMiladyCloudApiKey<br/>hasClaudeSubscriptionAuth<br/>readMiladyEnvKey(PARALLAX_DEFAULT_AGENT_TYPE)
        Config-->>Compat: { env.PARALLAX_LLM_PROVIDER, cloud.apiKey, ... }
        Compat->>Compat: cloudReady = llmProvider==cloud && apiKey present
        Compat->>Compat: claudeReady = cloudReady OR subscriptionAuth OR apiKey
        Compat-->>Preflight: FrameworkState
        Preflight-->>UI: AgentPreflightResult[]
        UI->>UI: Check auth.status === authenticated
    end
Loading

Fix All in Claude Code Fix All in Cursor Fix All in Codex

Reviews (4): Last reviewed commit: "fix(cloud-coding-agents): delete dead co..." | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

⚠️ Greptile suggestions auto-apply failed. The initial Greptile review stands. The weighted final verdict will be produced from the initial review only.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The gh pr comment call needs your approval to post. Here's the full review ready to go:


Decision: REQUEST CHANGES (preliminary, awaiting Greptile)

Five substantive required changes:

  1. Logic bugvalid: false for Claude credentials with null expiresAt (older blob format). Fix: blobExpiresAt !== null ? blobExpiresAt > Date.now() : true. Needs a test case.

  2. SecuritytriggerAuth() return value passed unsanitized to the browser via json(res, result) at server.ts:4630. The UI renders result.url as a clickable <a href>. Server should whitelist fields before forwarding.

  3. Supply chaincoding-agent-adapters@0.16.3 is unaudited. Needs source review confirming triggerAuth() returns no credential fields and createAdapter validates unknown types.

  4. Blast radiusdeploy/cloud-agent-template/package.json silently switches from workspace:* to pinned elizaOS versions with no explanation in the PR description. Needs justification or revert.

  5. ReliabilityPOST /api/coding-agents/auth/:agent has no server-side timeout. A hanging CLI auth process in headless/Docker leaves a dangling async for up to 2 minutes.

What's good: The readClaudeCodeOAuthBlob() / async importClaudeCodeOAuthToken() refactor is clean and well-reasoned. The get-subscription-status.test.ts regression suite is exactly the right kind of guard. Codex-through-cloud gating is the correct call. Universal invariants are untouched.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
…aude

- server.ts auth route: return 4xx when triggerAuth() yields no
  result (HTTP 200 was causing the client's res.ok check to pass
  and kick off a spurious 2-minute polling loop). Add a 15s
  server-side timeout so hanging CLI auth subprocesses in headless/
  Docker environments don't pin an async indefinitely. Whitelist
  response fields (launched, url, deviceCode, instructions) before
  forwarding to the browser so the adapter's untyped response shape
  can't leak tokens or internal secrets in unexpected fields. Stop
  echoing raw adapter error strings to the client.
- credentials.ts: treat a parseable Claude Code OAuth blob with
  null expiresAt as valid. Older `.credentials.json` payloads omit
  the field entirely — the previous check reported them as
  `valid: false`, which would have prompted re-auth on users with
  a working Claude Code install. The presence of an accessToken
  is itself evidence of authentication; the runtime refreshes
  via the refresh token on first use.
- Add regression test for the null-expiresAt legacy blob format.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

I have enough information for a complete review. Let me write it up.


Preliminary — awaiting Greptile deep review. A final weighted verdict will be posted once Greptile responds.


PR #1757 — feat(cloud-coding-agents): Eliza Cloud as provider for CLI coding agents


1. Classification (derived): feature — consistent with author's claim. The diff confirms: new LLM provider routing path, auth credential reader refactor, new API route, settings UI rewrite, and plugin version bump.

2. Rubric (derived): Auth credential correctness and security (new route + credential reader refactor), new npm dependency supply chain, settings UI i18n conventions, and API route sanitization completeness are the load-bearing axes for this PR.

3. Scope verdict: needs deep review — new auth route touching credential flows, new npm dependency (coding-agent-adapters added as direct dep to packages/agent), 1047 additions from a trust:probationary contributor, partial feature behind upstream cloud PRs not yet merged.

4. Universal invariants: all intact — eliza.ts, run-node.mjs, and agent.ts NODE_PATH sites are not in the diff. patch-deps.mjs is untouched. Electrobun try/catch guards are untouched. No access control files touched. No hardcoded ports introduced.

5. Judgment:

  • Needed? — OK. The Promise-truthy bug fix in getSubscriptionStatus() is a real correctness defect (function promoted to async but callers not updated → all users appeared configured). The cloud provider plumbing is mission-aligned. Both would be useful independently.

  • Better than existing? — OK. readClaudeCodeOAuthBlob()getSubscriptionStatus() sync path is cleaner than the prior importClaudeCodeOAuthToken() call that silently returned a Promise object. The async importClaudeCodeOAuthToken() path is correctly preserved for applySubscriptionCredentials() where await is already present.

  • Duplication? — OK with caveat. handleCodingAgentsFallback is duplicated between coding-agent-bridge.ts (exported, unused) and server.ts (private, wired). The PR correctly adds the auth route only to the live server.ts copy and adds a NOTE in the bridge explaining why the route is absent there. The duplication is pre-existing tech debt, not introduced here.

  • Blast radius covered? — CONCERN: missing one site. The @elizaos/plugin-agent-orchestrator pin is changed from workspace:* to 0.6.1 in both package.json and packages/agent/package.json. This means the submodule under plugins/plugin-agent-orchestrator (now pointing to ad3bf3c39) is no longer linked via workspace:* during local development. Developers who modify the plugin locally won't see changes picked up unless they re-run setup:upstreams. The PR doesn't update CLAUDE.md or developer docs to reflect this. Also: the deploy/cloud-agent-template/package.json change from workspace:* to pinned versions is intentional (deploy template can't use workspace), but has no documentation of its maintenance path.

  • Logic sound? — CONCERN (mild): authResult.url is rendered as <a href={authResult.url}> without validating the URL scheme. The server sanitizes typeof r.url === "string" but does not check the scheme. React 17+ logs a warning for javascript: URLs but doesn't unconditionally block them in all render environments. Fix: validate r.url.startsWith("https://") || r.url.startsWith("http://") before adding to sanitized in server.ts. The debounced auto-save pattern is correct (cleanup function returns clearTimeout(timer)). The autoSaveArmedRef skip-initial-load guard is correct. Auth poll cleanup on unmount is correct. getFrameworkState is cached for 15 seconds, so the two new readMiladyEnvKey/readMiladyCloudApiKey file reads land inside a 15s cache window — not a hot path issue.

  • Complexity appropriate? — OK. The _-prefixed synthetic key filtering in auto-save is well-motivated and documented with a comment. The cloudReady branch in computeFrameworkState with the explicit Codex exclusion comment is clear and honest about the upstream dependency state.

  • Tested meaningfully? — CONCERN. The get-subscription-status.test.ts regression test is excellent — it explicitly documents the Promise-truthy failure mode and guards against it with a synchronous-return assertion. However, the new POST /api/coding-agents/auth/:agent route has no tests — no coverage for the timeout path, the unknown-adapter path, or the response sanitization. For an auth-touching route from a probationary contributor, this is a gap.

  • Matches conventions? — CONCERN. The existing CodingAgentSettingsSection.tsx uses t() throughout. The new additions (LLM Provider label, all three provider descriptions, Anthropic/OpenAI/Google API key labels, cloud connection state messages, auth button text, auth result text including device code and instructions) are hardcoded English strings. The consistent use of t() in the rest of the file makes these omissions visible. The useTimeout hook from ../../hooks is removed in favor of setTimeout directly — this is fine functionally (cleanup is correct) but is an inconsistency with the hooks-based approach used elsewhere in the codebase.

  • Plausible breakage mode: The autoSaveArmedRef guard prevents the initial load from triggering a save. But loading is set false and autoSaveArmedRef is armed in the same effect pass. If prefs changes in the same React render cycle that loading flips to false (e.g., if setLoading(false) and setPrefs(loaded) are batched in React 18 automatic batching), the armed ref fires in the same effect that would otherwise skip — resulting in an immediate save of the load snapshot on first render. This is low-probability but worth noting. Also: the PARALLAX_DEFAULT_AGENT_TYPE preference is now written on tab click (onClick={() => { setActiveTab(agent); setPref("PARALLAX_DEFAULT_AGENT_TYPE", agent); }}), which auto-saves. Previously this required explicit Save. A user clicking tabs to explore options will now persist each click to disk.


6. PR-type-specific checks (feature + auth route + UI):

Check Result
New route uses \w+ regex — prevents path traversal OK
Auth route response whitelist (only launched, url, deviceCode, instructions) OK
15s timeout on auth trigger — prevents indefinite hang in headless env OK
agentType interpolated in error string (no injection risk — \w+ only) OK
authResult.url scheme not validated before rendering as <a href> CONCERN
coding-agent-adapters declared direct dep — supply chain origin clear? CONCERN — generic unprefixed name, auth-sensitive; needs explicit vetting note
@elizaos/plugin-agent-orchestrator workspace pin broken for local dev CONCERN
New i18n strings in CodingAgentSettingsSection.tsx bypass t() CONCERN
Test coverage for Promise-truthy regression OK — excellent
Test coverage for new auth route CONCERN — missing
Submodule bump consistent with package.json version OK
_CLOUD_API_KEY synthetic key filtered from auto-save env patch OK
Codex-through-cloud correctly blocked (upstream PRs pending) OK — well-documented
getFrameworkState 15s cache contains new file reads OK — no hot path regression

7. Security: concerns (non-critical)

  1. authResult.url rendered as <a href={...}> without scheme validation in server.ts sanitizer. Mitigated by React 17+'s javascript: URL handling, but explicit validation is stronger defense-in-depth.
  2. ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY are now stored plaintext in milady.json via auto-save. This is a pre-existing pattern in this codebase (not introduced by this PR), but the surface area is expanded here.
  3. coding-agent-adapters is a new direct dependency with an unprefixed npm name and auth-flow responsibilities. The package appears in the codebase's own test fixtures which suggests it's a known project dep — but a provenance note would be appropriate for audit trail purposes.

8. Decision: REQUEST CHANGES

Blocking asks:

  1. URL scheme validation in server.ts sanitizer: reject url values that don't start with https:// or http:// before forwarding to the browser.
  2. i18n: route new user-facing strings through t() or add them to the translation catalog. The existing file consistently uses t().

Non-blocking asks (should fix before merge, won't hold):
3. Add a test for POST /api/coding-agents/auth/:agent covering: timeout path (verify 504), unknown agent type (verify 400 or 500), and sanitized response (verify accessToken is NOT forwarded).
4. Document in CLAUDE.md or a comment that @elizaos/plugin-agent-orchestrator is now pinned to a specific npm version and that setup:upstreams is required to pick up local plugin changes.

@greptileai please perform a deep review — this PR was flagged as needing deep analysis by agent-review.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
…tests

- server.ts auth route: extract response sanitizer into
  `coding-agents-auth-sanitize.ts` and reject `url` values that
  don't parse as `http:` or `https:`. Defense in depth against a
  malicious/compromised adapter smuggling `javascript:`, `data:`,
  or `file:` URLs through an <a href>. React's built-in sanitizer
  also blocks these, but explicit server-side validation is
  stronger and keeps the UI layer honest.
- Add coding-agents-auth-sanitize.test.ts covering whitelist
  enforcement (accessToken / refreshToken / apiKey dropped),
  scheme acceptance (http, https), scheme rejection (javascript,
  data, file, malformed), and null/non-object input handling.
- CodingAgentSettingsSection: route new user-facing strings
  through t() to match the rest of the file — LLM Provider label
  and options, API-key field labels and descriptions, cloud-pair
  status, per-agent Authenticate/Authenticating button labels,
  sign-in link, device-code line, Retry button.
- CLAUDE.md: document that @elizaos/plugin-agent-orchestrator is
  pinned to an exact published version (0.6.1) and that
  `bun run setup:upstreams` is required to develop against a
  local checkout of the plugin.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added the docs label Apr 8, 2026
@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
…ht auth shape

- CodingAgentSettingsSection: add `.catch` to the debounced
  updateConfig call so a failed POST surfaces an inline error
  banner instead of silently dropping the user's typed API key.
  Restores the error-feedback surface SaveFooter used to own —
  the previous fire-and-forget would leave `prefs` populated with
  a key that was never persisted, so a restart would lose it.
- Add `coding-agents-preflight-normalize.ts` that validates the
  adapter's `auth` field at the HTTP boundary. Previously the
  server forwarded `raw.auth as Record<string, unknown>` while
  the client typed it as a specific 4-field struct; a shape
  drift in the adapter would silently break the UI's `needsAuth`
  check and the Authenticate button would never render.
  Coerces unknown statuses to "unknown" and drops any field the
  adapter might smuggle in beyond the whitelist (`status`,
  `method`, `detail`, `loginHint`).
- Wire the normalizer into both `handleCodingAgentsFallback`
  copies (coding-agent-bridge.ts + server.ts) and share the type
  via import.
- 7 regression tests for the normalizer covering null input,
  status coercion, field whitelisting, and non-string handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The review is complete. Here is the full structured verdict:


Preliminary — awaiting Greptile deep review.


PR #1757 — Review

1. Classification (derived): Feature — consistent with author's claim.

2. Rubric (derived): Security of the new process-spawning route, supply chain risk on coding-agent-adapters (authored by the PR contributor), correctness of the credentials.ts Promise-truthy fix, UI auto-save leak safety.

3. Scope verdict: Needs deep review — new process-spawning API route via a package owned by a probationary contributor, credential-reading refactor, 439-line UI rewrite.

4. Universal invariants: All intact. NODE_PATH untouched in all three sites, patch-deps preserved, Electrobun guards intact, no access control files modified, no hardcoded ports.

5. Judgment:

  • Needed? — OK
  • Better than existing? — OK
  • Duplication? — OK
  • Blast radius covered? — CONCERN: coding-agent-bridge.ts has zero importers — ALL changes to it in this PR are dead code. The NOTE comment inside one function is insufficient; the whole file is inert.
  • Logic sound? — OK
  • Complexity appropriate? — OK
  • Tested meaningfully? — OK — 3 test files, ~370 lines, all testing the actual introduced change
  • Matches conventions? — CONCERN (minor): PARALLAX_LLM_PROVIDER is a new env key not documented anywhere
  • Plausible breakage mode: readClaudeCodeOAuthBlob() calls execSync to the macOS keychain synchronously on every settings request — pre-existing issue but not improved.

6. PR-type-specific checks: Auth route regex-constrained (\w+), sanitizeAuthResult URL whitelist tested, no credential leaks in error messages, auto-save timer cleaned up on unmount, auth poll cleared on unmount, _CLOUD_API_KEY correctly excluded from round-trip save, coding-agent-adapters already a transitive dep (mitigates supply chain concern, does not eliminate it).

7. Security:

  • Primary concern: coding-agent-adapters@0.16.3 is maintained by haruhunab1320 <jakob@magickml.com> — the same person who authored this PR — and is being promoted from transitive to direct dependency with process-spawning capabilities. Mitigating: MIT, 52 versions, already in the dep tree, named author. Needs independent verification.
  • Secondary concern: coding-agent-bridge.ts is dead code. Future contributors could add security changes to the dead copy while the live server.ts path goes unpatched.
  • Otherwise clear.

8. Decision: REQUEST CHANGES

[BLOCK 1] coding-agent-bridge.ts dead code must be explicitly addressed — either delete the file or add a prominent header warning that it has zero importers and all live code is in server.ts.

[BLOCK 2] Supply chain disclosure required: the PR author is the sole maintainer of coding-agent-adapters. The PR description must explicitly acknowledge this and link to the package source for independent review.

[Non-blocking] Document PARALLAX_LLM_PROVIDER in CLAUDE.md; call out the silent defaultAgentType-via-tab-click behavioral change for QA clarity.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
HaruHunab1320 and others added 2 commits April 8, 2026 12:35
…li-provider

# Conflicts:
#	plugins/plugin-agent-orchestrator
…t PARALLAX_LLM_PROVIDER

- Delete packages/agent/src/api/coding-agent-bridge.ts entirely. The
  exported handleCodingAgentsFallback had zero importers across the
  repo — the live preflight/auth route wiring all lives in server.ts's
  private copy of the same function. Leaving the bridge file around
  was actively dangerous: a future contributor could patch a security
  fix into the dead copy while the live server.ts path goes unchanged.
  The NOTE comment added earlier was insufficient; the whole file
  needed to go.
- Document PARALLAX_LLM_PROVIDER in CLAUDE.md's env var table with
  its three valid values (subscription / api_keys / cloud), where
  it's set (Coding Agents settings UI), and where it's consumed
  (agent-orchestrator-compat.ts). The PARALLAX_* namespace is owned
  by @elizaos/plugin-agent-orchestrator upstream; renaming is a
  follow-up that should rename the whole namespace at once.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The GitHub write operations require user approval. Here is the full review ready to post:


Preliminary — awaiting Greptile deep review. A final weighted verdict will be posted once Greptile responds.


1. Classification (derived): feature — consistent with author's claim. Multi-layer: auth plumbing (credentials.ts, agent-orchestrator-compat.ts), new API route (server.ts), boundary sanitizers (2 new modules + tests), UI rewrite (CodingAgentSettingsSection.tsx), and a terminal palette addition.

2. Rubric (derived): Correctness of the async→sync split in getSubscriptionStatus; security of the new auth route and its response forwarding path; supply chain trust of the new unscoped coding-agent-adapters dep; whether cloudReady can be spoofed.

3. Scope verdict: needs deep review — feature + auth changes + new npm dep + significant UI rewrite from a probationary contributor.

4. Universal invariants: all intact — NODE_PATH files, patch-deps.mjs, Electrobun try/catch guards, access control files, hardcoded port checks all pass.

5. Judgment:

  • Needed? — OK. The getSubscriptionStatus Promise-truthy bug is a real correctness issue (every user appeared configured regardless of reality). Cloud provider pathway is mission-relevant.
  • Better than existing? — OK. readClaudeCodeOAuthBlob() sync helper is demonstrably correct vs. calling async without await.
  • Duplication? — OK. Sanitizer modules don't duplicate existing patterns. UI uses @miladyai/ui primitives correctly.
  • Blast radius covered? — CONCERN: bun.lockb absent from diff. Adding coding-agent-adapters: 0.16.3 must update the lockfile to pin the integrity hash — without it reviewers can't verify what ships.
  • Logic sound? — CONCERN (minor): Auth POST failure silently clears authInProgress with no user-facing error. The Promise.race sentinel pattern is correct.
  • Complexity appropriate? — CONCERN (minor): CodingAgentSettingsSection.tsx hits ~1,000 LOC, at the edge of the 500 LOC guideline.
  • Tested meaningfully? — OK. get-subscription-status.test.ts pins the sync contract with a hermetic sandbox. Sanitizer tests cover javascript:/data:/file: rejection.
  • Matches conventions? — OK. Import ordering is Biome auto-fixes. elizaOS casing correct. No any added.
  • Plausible breakage mode: cloudReady reads milady.json on every computeFrameworkState call. A concurrent debounced save that partially flushes the file causes readJsonFile to return null, momentarily resetting cloudReady to false until the next poll.

6. PR-type-specific checks:

  • Auth route \w+ validation: OK
  • sanitizeAuthResult URL scheme check: OK — confirmed by tests
  • normalizePreflightAuth secret field whitelist: OK — confirmed by tests
  • cloudReady requires both PARALLAX_LLM_PROVIDER=cloud AND cloud.apiKey: OK — read from file at call time, not cacheable
  • Codex NOT gated on cloudReady pending cloud#427+428: OK — well-documented
  • Dual handleCodingAgentsFallback copies: CONCERN — guard comment is necessary but architecturally fragile
  • authPollRef unmount cleanup: OK
  • _CLOUD_API_KEY round-trip prevention: OK

7. Security:

  • CONCERN: coding-agent-adapters is unscoped on npm — no org-level squatting protection. Pinned to 0.16.3 is good but missing lockfile means no integrity hash proof. Required: confirm team owns the npm account, include bun.lockb, or scope under @miladyai/.
  • CONCERN: catch (e) in auth route swallows the internal error entirely before returning 500. Log at warn internally.
  • CLEAR: No prompt injection. Credential export policy preserved. Access control files untouched. Dev observability endpoints intact.

8. Decision: REQUEST CHANGES

Required before merge:

  1. Include bun.lockb update with coding-agent-adapters@0.16.3 integrity hash
  2. Confirm npm ownership of coding-agent-adapters or scope it under @miladyai/
  3. Surface a user-facing error when POST /api/coding-agents/auth/:agent returns non-ok instead of silently clearing the spinner
  4. Log internal adapter errors (not to client) in the catch block before returning 500

@greptileai please perform a deep review — this PR was flagged as needing deep analysis by agent-review.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The review is complete. Here's what I found:


PR #1757 — feat(cloud-coding-agents): Eliza Cloud as provider for CLI coding agents

Decision: REQUEST CHANGES (preliminary, awaiting Greptile deep review)

Classification: feature + bug-fix + refactor. The bug fix (Promise-truthy in getSubscriptionStatus) is the most immediately impactful change — previously every user appeared to have a valid Anthropic subscription configured because importClaudeCodeOAuthToken() was async but called synchronously, making the Promise object always truthy. Good catch.

Universal invariants: All intact. NODE_PATH, patch-deps.mjs, Electrobun guards, namespace, ports, access control files — none touched.

Required changes before merge:

  1. agentType allowlist in the auth routePOST /api/coding-agents/auth/:agent uses (\w+) and passes the value directly to createAdapter(agentType as AdapterType). No runtime validation. \w+ allows __proto__, constructor, etc. Fix is two lines: check against ["claude", "codex", "gemini", "aider"] and return 400 otherwise.

  2. Server-side error logging in auth catch block — the outer catch suppresses err entirely (correct for response sanitization, wrong for production debugging). Add logger.error(...) before the error(res, ...) call.

  3. CodingAgentSettingsSection.tsx file size — 676 lines on base branch, ~1024 after the PR. The provider-selector, API-key inputs, auth-flow banner, and model-config section are already logically separated — extract them into sub-components to comply with the ~500 LOC guideline.

Strengths: The getSubscriptionStatus regression tests are excellent (pin the sync contract, mock the keychain, cover all edge cases). The sanitizeAuthResult and normalizePreflightAuth unit tests are thorough. The cloudReady gate intentionally excludes Codex with a clear comment pending upstream PRs — honest and conservative. The bridge consolidation (coding-agent-bridge.tsserver.ts) is a clean simplification.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:probationary Building trust, closer scrutiny (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
…plit settings UI

- server.ts auth route: validate agentType against a 4-item allowlist
  (claude/codex/gemini/aider) before passing to createAdapter. The
  \w+ regex on the URL blocks path traversal but still accepts
  arbitrary identifiers like __proto__, constructor, or any future
  adapter name the package happens to export. Gate on the shapes the
  UI actually ships today.
- server.ts auth route: log the full error (stack + message) via
  logger.error in the catch block before returning the generic
  client-facing message. The outer catch was correctly sanitizing
  the response but silently dropping production-debug info.
- Split CodingAgentSettingsSection.tsx (1064 LOC) into five smaller
  modules, bringing the parent to 444 LOC (under the ~500 guideline):
    - coding-agent-settings-shared.ts — types, constants, fallback
      model lists (128 LOC)
    - LlmProviderSection.tsx — LLM provider select + api_keys inputs
      + cloud pair status (174 LOC)
    - GlobalPrefsSection.tsx — selection strategy, approval preset,
      scratch retention, coding directory (199 LOC)
    - AgentTabsSection.tsx — segmented agent tabs, per-agent auth
      flow, auth-result banner, availability line (200 LOC)
    - ModelConfigSection.tsx — aider provider, powerful/fast model
      selects, fallback hint (150 LOC)
  Parent now owns state + load/save effects + handlers + render
  orchestration only. Update CodingAgentSettingsSection.test.tsx to
  import ADAPTER_NAME_TO_TAB from the new shared module.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The review is ready but requires user approval to post. Here is the full review output:


Preliminary — awaiting Greptile deep review. A final weighted verdict will be posted once Greptile responds.


1. Classification (derived): feature — consistent with author's claim. Multi-layer: runtime/credentials + new API route + plugin version pin + settings UI refactor.

2. Rubric (derived): Auth correctness (Promise-truthy bug fix), new API route security (allowlist + sanitization), credential handling at HTTP boundaries, UI decomposition within ~500 LOC conventions, supply-chain for new coding-agent-adapters dependency.

3. Scope verdict: needs deep review

4. Universal invariants: all intact. All three NODE_PATH sites, patch-deps.mjs, Electrobun startup guards, milady namespace, no hardcoded ports, dynamic imports only, access control files — all untouched.

5. Judgment:

  • Needed? — OK. Real bug fixed (Promise-truthy in getSubscriptionStatus, every user appeared configured regardless of reality) + real user value (cloud auth flow).
  • Better than existing? — OK. readClaudeCodeOAuthBlob() returning a structured blob vs. raw string gives callers expiry data without a second keychain read.
  • Duplication? — OK. coding-agent-bridge.ts deletion removes genuine duplication — server.ts already had private copies of all exported functions. Verified via grep: zero remaining imports.
  • Blast radius covered? — OK. All five changed layers have diffs. deploy/cloud-agent-template workspace:* → pinned versions is correct for non-monorepo deploy.
  • Logic sound? — OK with note. autoSaveArmedRef correctly skips initial load. _CLOUD_API_KEY filtered from env patch. authPollRef cleanup correct on unmount/retry. Sync/async boundary in getSubscriptionStatus preserved. Note: readMiladyCloudApiKey() reads config file on every framework state computation — sync I/O per settings poll.
  • Complexity appropriate? — OK. Five-file UI decomposition justified by ~500 LOC guideline.
  • Tested meaningfully? — OK. sanitizeAuthResult (URL scheme rejection + whitelist), normalizePreflightAuth (status coercion + no token leak), getSubscriptionStatus (Promise-truthy regression pin, blob parsing, expiry) — all exercise the actual change.
  • Matches conventions? — OK. Minor: instructions in AuthResult is non-optional but SanitizedAuthResult.instructions is optional — non-breaking inconsistency.
  • Plausible breakage mode: readClaudeCodeOAuthBlob() shells to macOS security (3s execSync timeout) on every /api/subscription/status call. Slow-keychain machines stall synchronously per poll.

6. PR-type-specific checks: All OK — auth route allowlist (Set.has() blocks __proto__/constructor), URL scheme validation, field whitelists, 15s timeout, poll cleanup, cloud key not leaked to env, Codex intentionally NOT cloudReady (pending cloud#427), bridge deletion verified clean.

7. Security: clear. TOS compliance preserved. _CLOUD_API_KEY not duplicated into env. triggerAuth() URL validated http/https before forwarding to browser.

8. Decision: APPROVE


Please approve the gh pr review command above to post this to GitHub. It requires write access to milady-ai/milady.

@github-actions github-actions bot added category:feature Auto-managed semantic PR category trust:contributing Active contributor, building track record (auto-managed) and removed trust:probationary Building trust, closer scrutiny (auto-managed) category:feature Auto-managed semantic PR category labels Apr 8, 2026
@HaruHunab1320 HaruHunab1320 merged commit f2176c3 into develop Apr 8, 2026
16 of 45 checks passed
@HaruHunab1320 HaruHunab1320 deleted the feat/eliza-cloud-cli-provider branch April 8, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build category:feature Auto-managed semantic PR category deploy docs tests trust:contributing Active contributor, building track record (auto-managed)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant