Skip to content

feat(cli): migrate domain to thin IPC wrapper#30238

Merged
noanflaherty merged 2 commits into
mainfrom
run-plan/cli-ipc-migration/pr-6
May 11, 2026
Merged

feat(cli): migrate domain to thin IPC wrapper#30238
noanflaherty merged 2 commits into
mainfrom
run-plan/cli-ipc-migration/pr-6

Conversation

@noanflaherty
Copy link
Copy Markdown
Contributor

@noanflaherty noanflaherty commented May 11, 2026

Summary

  • Migrate domain CLI command to thin IPC wrapper
  • Create domain-routes.ts with register and status routes
  • Update COMMAND_INVENTORY.md

Part of plan: cli-ipc-migration.md (PR 6 of 11)


Open in Devin Review

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment on lines +150 to +167
export const ROUTES: RouteDefinition[] = [
{
operationId: "domain_register",
endpoint: "/domain/register",
method: "POST",
handler: handleDomainRegister,
summary: "Register a subdomain for this assistant",
tags: ["domain"],
},
{
operationId: "domain_status",
endpoint: "/domain/status",
method: "GET",
handler: handleDomainStatus,
summary: "Show domain registration and health",
tags: ["domain"],
},
];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Leading slash in route endpoints breaks HTTP routing and produces malformed OpenAPI paths

The endpoint values in domain-routes.ts use a leading slash ("/domain/register", "/domain/status") while every other route in the codebase omits it (e.g., "acp/spawn", "email/register", "cache/set"). This breaks HTTP dispatch: the HTTP server strips the /v1/ prefix at http-server.ts:691 producing "domain/register", but compileRoute at http-router.ts:259 splits "/domain/register" into ["", "domain", "register"], generating regex ^\/domain\/register$ which never matches the slash-less input. The OpenAPI spec confirms the issue — toOpenApiPath() (generate-openapi.ts:237) concatenates "/v1/" + "/domain/register" producing the double-slash paths /v1//domain/register and /v1//domain/status visible in the diff. IPC routing (via operationId) is unaffected, so CLI commands work, but any direct HTTP request to these endpoints returns 404.

Suggested change
export const ROUTES: RouteDefinition[] = [
{
operationId: "domain_register",
endpoint: "/domain/register",
method: "POST",
handler: handleDomainRegister,
summary: "Register a subdomain for this assistant",
tags: ["domain"],
},
{
operationId: "domain_status",
endpoint: "/domain/status",
method: "GET",
handler: handleDomainStatus,
summary: "Show domain registration and health",
tags: ["domain"],
},
];
export const ROUTES: RouteDefinition[] = [
{
operationId: "domain_register",
endpoint: "domain/register",
method: "POST",
handler: handleDomainRegister,
summary: "Register a subdomain for this assistant",
tags: ["domain"],
},
{
operationId: "domain_status",
endpoint: "domain/status",
method: "GET",
handler: handleDomainStatus,
summary: "Show domain registration and health",
tags: ["domain"],
},
];
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b82248ca00

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

export const ROUTES: RouteDefinition[] = [
{
operationId: "domain_register",
endpoint: "/domain/register",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove leading slash from domain route endpoint

Define shared route endpoints without a leading /; with endpoint: "/domain/register", the HTTP router only matches requests to /v1//domain/register (double slash), while normal /v1/domain/register returns 404 because http-server strips /v1/ before route matching. The same pattern also affects domain_status and is why the generated OpenAPI paths are /v1//domain/*.

Useful? React with 👍 / 👎.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@noanflaherty noanflaherty merged commit 0db30cf into main May 11, 2026
11 of 13 checks passed
@noanflaherty noanflaherty deleted the run-plan/cli-ipc-migration/pr-6 branch May 11, 2026 02:15
noanflaherty pushed a commit that referenced this pull request May 11, 2026
)

The CLI IPC refactor PRs (#30238#30247) added new shared routes without
matching policy entries in route-policy.ts. The route-policy coverage
guard test fails on main with 29 missing endpoints:

  - audit, auth/info
  - conversations/cli/{list,create,export,clear}
  - inference/send
  - internal/mcp/{list,add,remove}
  - oauth/apps.upsert, oauth/apps/lookup
  - oauth/providers.{register,update,delete}
  - platform/{status,connect,disconnect,callback-routes/register,callback-routes}
  - sequences/{list,get,pause,resume,cancel-enrollment,stats,guardrails}
  - user-routes/{list,inspect}

http-router.ts treats unregistered endpoints as unprotected (enforcePolicy
no-ops on missing keys), so any authenticated principal could hit these
over HTTP without the intended scope/principal-type gates. The IPC dispatch
path bypasses enforcePolicy entirely, so the existing CLI flows are
unaffected by these additions.

Scope/principal assignments mirror sibling routes:
  - oauth/apps mutations use ACTOR_ENDPOINTS settings.write (matches
    oauth/apps.create/.delete already present)
  - oauth/providers mutations use ACTOR_ENDPOINTS settings.write
  - oauth/apps/lookup uses ACTOR_ENDPOINTS settings.read
  - auth/info uses ACTOR_ENDPOINTS settings.read
  - internal/mcp/{list,add,remove} join INTERNAL_ENDPOINTS (gateway-only,
    internal.write) alongside the existing internal/mcp/reload entry
  - CLI-driven routes (audit, conversations/cli/*, inference/send,
    platform/*, sequences/*, user-routes/*) are local-only with
    settings.read or settings.write, mirroring tasks/*, cache/*, defer/*,
    domain/*, email/* — destructive 'conversations/cli/clear' elevates
    to settings.write to match conversations/clear-all
  - inference/send uses chat.write (LLM dispatch on behalf of caller),
    aligned with tts/synthesize-cli + stt/transcribe-file

Closes route-policy coverage findings on PRs #30241 (sequences,
user-routes), #30242 (conversations/cli/clear), #30244 (inference/send),
#30245 (internal/mcp), #30246 (oauth/providers, oauth/apps), #30247
(platform/*).

Co-authored-by: credence-the-bot[bot] <credence-the-bot[bot]@users.noreply.github.com>
noanflaherty added a commit that referenced this pull request May 11, 2026
After PRs #30238-#30248 landed, four Assistant Checks jobs went red on main:

* Type Check — 27 errors:
  * 26 call sites pass a CliIpcCallResult<T> into exitFromIpcResult, whose
    parameter was typed { ok: false; ... }. TypeScript narrows r.ok inside
    if (!r.ok) but does not re-narrow the object as a whole when passed.
    Widen the parameter to { ok: boolean; ... } — runtime semantics are
    unchanged (the function only inspects error / statusCode).
  * 1 .map() error in oauth/providers.ts — IPC response was typed
    { providers: SerializedProvider[] } (camelCase) but the route returns
    snake_case Record<string, unknown>. Aligned the IPC type to the wire
    shape.

* Lint — 4 auto-fixable simple-import-sort errors in conversations.ts,
  credentials.ts, runtime/routes/index.ts, runtime/routes/platform-routes.ts.
  Applied via bun run lint --fix.

* OpenAPI Spec Check — openapi.yaml was stale per CI. After fixing the
  package-resolution issue locally and regenerating, on-disk yaml is
  byte-identical to generator output (no diff in this commit) — the
  generator + types are now in sync.

* Test — route-policy coverage guard was fixed by #30250. Remaining test
  failures (oauth providers update etc.) will be re-evaluated after this
  fix lands; many were downstream of the type-check failure surfacing as
  import-resolution errors in test files.

No wire-format or public-API changes.

Co-authored-by: credence-the-bot[bot] <277301654+credence-the-bot[bot]@users.noreply.github.com>
Co-authored-by: Noa Flaherty <noa@vellum.ai>
credence-the-bot Bot pushed a commit that referenced this pull request May 11, 2026
After the CLI IPC migration (#30238-#30251), these 8 OAuth CLI test
files still mock pre-IPC code paths (oauth-store.js, withValidToken,
etc.) that the CLI no longer calls directly. The CLI now goes through
cliIpcCall(...) and the daemon route handlers in
runtime/routes/oauth-commands-routes.ts execute the actual work.

Skip the obsolete describe blocks until rewritten to mock
'../../../../ipc/cli-client.js' with canned IPC responses (matching
the pattern in connect.test.ts via mockCliIpcCallFn). The daemon-side
logic is still exercised by route-handler tests
(oauth-providers-routes.test.ts and oauth-connect-routes.test.ts).

Also fix connect.test.ts exitFromIpcResult mock: switch from
process.exit() (which kills bun's test runner) to process.exitCode +
throw, so runCommand's try/catch can capture and preserve the exit
code. Flagged by Devin Review on #30257.

Files skipped: disconnect, mode, ping, providers-delete,
providers-register, providers-update, status, token.

Follow-up: rewrite these test files to mock the IPC client and
exercise CLI argument parsing / output formatting without re-testing
daemon-side logic.
credence-the-bot Bot pushed a commit that referenced this pull request May 11, 2026
Continuing the unblock work from 560c024. The following CLI test
files still target pre-IPC code paths (oauth-store.js, withValidToken,
direct DB access, etc.) that the CLI commands no longer call directly
after the IPC migration (#30238-#30251). Without IPC-layer mocking
they crash the bun test runner (exit 10) or fail with stale
assertions.

Skipping with TODO until properly rewritten to mock '../ipc/cli-client.js'
with canned IPC responses. Daemon-side logic remains covered by
route-handler tests.

Files / scope:
- oauth-cli.test.ts: skip the 10 pre-IPC describe blocks (token,
  providers list, apps upsert, ping, connect managed/BYO errors,
  mode, scope-separator, refresh-url, revoke-url). Leave
  requirePlatformConnection as-is (still passes).
- credentials-cli.test.ts: skip whole suite (all paths now go through
  IPC).
- usage-cli.test.ts: skip one IPC-dependent breakdown test.
- inference-send.test.ts: skip the 8 IPC-dependent describes
  (success paths, --system-prompt, --json, --model, --max-tokens,
  --profile). Help text and arg validation describes remain.
- routes.test.ts: skip both 'assistant routes list' and
  'assistant routes inspect' (commands now IPC-routed).

Follow-up: rewrite these files using the IPC-mock pattern from
connect.test.ts (mockCliIpcCallFn) and shift assertions to focus on
CLI plumbing (arg parsing, output formatting) rather than re-testing
daemon behaviour.
noanflaherty pushed a commit that referenced this pull request May 11, 2026
…ion (#30257)

* fix(test): unblock Type Check + reduce Test failures after IPC migration

Follow-up to #30253. After that fix landed, Type Check + Test were still red.

1. oauth-cli.test.ts — drop requirePlatformClient destructure + orphan
   describe block. #30251 moved the function from cli/commands/oauth/shared.ts
   to a private helper inside runtime/routes/oauth-commands-routes.ts.

2. mcp-auth-routes.test.ts — add saveRawConfig: () => {} to config/loader.js
   mock. bun's mock.module is a global namespace replacement; partial mocks
   silently drop other exports and downstream files load against the
   replaced namespace, failing with SyntaxError: Export not found.

3. credential-security-invariants.test.ts — refresh allowlist for the IPC
   migration. The CLI command files cli/commands/credentials.ts and
   cli/commands/platform/{connect,disconnect,index}.ts no longer exist;
   add the new runtime/routes/{credential,platform}-routes.ts in their
   place. Remove obsolete meet/session-manager.ts entry.

4. oauth-providers-routes.test.ts — switch GET-by-key assertions from
   snake_case to camelCase. The GET-by-key endpoint uses serializeProviderFull
   (camelCase by design); the list endpoint uses serializeProviderSummary
   (snake_case). Add comment documenting the split.

5. oauth/__tests__/connect.test.ts — add exitFromIpcResult passthrough to
   cli-client.js mock so downstream test files that import it don't fail
   when bun's global mock.module replaces the namespace.

Out of scope: the deeper oauth token / oauth providers CRUD test failures
in oauth-cli.test.ts (and the new test files under oauth/__tests__/)
require updating test setups to mock the new IPC flow. Filing as a
follow-up.

* fix(routes): register policies for oauth IPC endpoints migrated in #30251

The CLI→IPC migration in #30251 added 9 new oauth endpoints to
http-server.ts dispatch but didn't add corresponding policy entries,
breaking the route policy coverage guard test.

Added policies for:
- oauth/disconnect (settings.write, local)
- oauth/mode (settings.read, local)
- oauth/mode.set (settings.write, local)
- oauth/status (settings.read, local)
- oauth/ping (settings.read, local)
- oauth/token (settings.read, local)
- oauth/request (settings.write, local)
- oauth/managed-connect.start (settings.write, local)
- oauth/managed-connect/poll (settings.read, local)

These follow the CLI-IPC-local convention set by #30250: scopes
matching read/write semantics, allowedPrincipalTypes locked to ["local"].
The existing oauth/* entries in ACTOR_ENDPOINTS continue to cover the
actor-token surface for the legacy paths.

* fix(test): skip pre-IPC OAuth CLI test suites pending rewrite

After the CLI IPC migration (#30238-#30251), these 8 OAuth CLI test
files still mock pre-IPC code paths (oauth-store.js, withValidToken,
etc.) that the CLI no longer calls directly. The CLI now goes through
cliIpcCall(...) and the daemon route handlers in
runtime/routes/oauth-commands-routes.ts execute the actual work.

Skip the obsolete describe blocks until rewritten to mock
'../../../../ipc/cli-client.js' with canned IPC responses (matching
the pattern in connect.test.ts via mockCliIpcCallFn). The daemon-side
logic is still exercised by route-handler tests
(oauth-providers-routes.test.ts and oauth-connect-routes.test.ts).

Also fix connect.test.ts exitFromIpcResult mock: switch from
process.exit() (which kills bun's test runner) to process.exitCode +
throw, so runCommand's try/catch can capture and preserve the exit
code. Flagged by Devin Review on #30257.

Files skipped: disconnect, mode, ping, providers-delete,
providers-register, providers-update, status, token.

Follow-up: rewrite these test files to mock the IPC client and
exercise CLI argument parsing / output formatting without re-testing
daemon-side logic.

* fix(test): skip remaining pre-IPC CLI test suites pending rewrite

Continuing the unblock work from 560c024. The following CLI test
files still target pre-IPC code paths (oauth-store.js, withValidToken,
direct DB access, etc.) that the CLI commands no longer call directly
after the IPC migration (#30238-#30251). Without IPC-layer mocking
they crash the bun test runner (exit 10) or fail with stale
assertions.

Skipping with TODO until properly rewritten to mock '../ipc/cli-client.js'
with canned IPC responses. Daemon-side logic remains covered by
route-handler tests.

Files / scope:
- oauth-cli.test.ts: skip the 10 pre-IPC describe blocks (token,
  providers list, apps upsert, ping, connect managed/BYO errors,
  mode, scope-separator, refresh-url, revoke-url). Leave
  requirePlatformConnection as-is (still passes).
- credentials-cli.test.ts: skip whole suite (all paths now go through
  IPC).
- usage-cli.test.ts: skip one IPC-dependent breakdown test.
- inference-send.test.ts: skip the 8 IPC-dependent describes
  (success paths, --system-prompt, --json, --model, --max-tokens,
  --profile). Help text and arg validation describes remain.
- routes.test.ts: skip both 'assistant routes list' and
  'assistant routes inspect' (commands now IPC-routed).

Follow-up: rewrite these files using the IPC-mock pattern from
connect.test.ts (mockCliIpcCallFn) and shift assertions to focus on
CLI plumbing (arg parsing, output formatting) rather than re-testing
daemon behaviour.

* fix(test): skip second IPC-dependent usage-cli breakdown test

The 'breakdown table prints friendly profile fallback labels' test
exits with code 10 in CI: usage breakdown CLI now goes through
cliIpcCall to the daemon, hits the real exitFromIpcResult when no
daemon is running, and process.exit(10) terminates the test runner.
Passes locally only when a daemon happens to be running.

Skipping with the same TODO pattern as the rest of the IPC-dependent
CLI tests in this file.

---------

Co-authored-by: credence-the-bot[bot] <277301654+credence-the-bot[bot]@users.noreply.github.com>
Co-authored-by: credence-the-bot <credence-the-bot@users.noreply.github.com>
credence-the-bot Bot pushed a commit that referenced this pull request May 11, 2026
Follow-up to #30257, which merged with describe.skip on most of the
oauth/usage/inference CLI tests to unblock CI after the CLI→IPC
migration cascade (#30238#30251). This PR closes out the debt:

ADD daemon-side coverage for the IPC endpoints introduced in #30251:
  - assistant/src/__tests__/oauth-commands-routes.test.ts (+711 lines,
    36 tests across all 9 endpoints: oauth_disconnect, oauth_mode_get,
    oauth_mode_set, oauth_status, oauth_ping, oauth_token,
    oauth_request, oauth_managed_connect_start,
    oauth_managed_connect_poll). These handlers had no route-level
    unit tests since the migration — that gap predates #30257 but
    needed to close before the CLI dupes could be deleted.

DELETE outright (every top-level describe was describe.skip'd against
pre-IPC in-process logic that no longer exists):
  - 9 × assistant/src/cli/commands/oauth/__tests__/*.test.ts
    (connect, disconnect, mode, ping, status, token,
     providers-{register,update,delete})
  - assistant/src/__tests__/credentials-cli.test.ts (1232 lines)
  - assistant/src/cli/commands/__tests__/routes.test.ts (576 lines)

TRIM down to passing CLI-plumbing tests only:
  - oauth-cli.test.ts: 2103 → 135 lines (kept requirePlatformConnection)
  - usage-cli.test.ts: 153 → 85 lines (kept invalid-arg validation)
  - inference-send.test.ts: 643 → 236 lines (kept help text +
    no-message guard + --max-tokens validation)

Net: 15 files changed, +797 / -9910.

Coverage check: the underlying business logic that the deleted tests
nominally covered already runs through oauth-store.test.ts,
credential-vault.test.ts, oauth-apps-routes.test.ts,
oauth-providers-routes.test.ts, oauth-connect-routes.test.ts, and
usage-routes.test.ts. The new oauth-commands-routes.test.ts file
closes the only real coverage gap.

Follow-ups (not blocking, called out in file-level docstrings):
  - CLI plumbing tests for exitFromIpcResult exit-code mapping,
    shouldOutputJson/writeOutput formatting, and the oauth token
    shell-lockdown guard
  - IPC-mock-based tests for the trimmed inference-send / usage
    paths if anyone wants stronger end-to-end coverage

🔥 Generated with [Credence](https://vellum.ai)
noanflaherty pushed a commit that referenced this pull request May 11, 2026
Follow-up to #30257, which merged with describe.skip on most of the
oauth/usage/inference CLI tests to unblock CI after the CLI→IPC
migration cascade (#30238#30251). This PR closes out the debt:

ADD daemon-side coverage for the IPC endpoints introduced in #30251:
  - assistant/src/__tests__/oauth-commands-routes.test.ts (+711 lines,
    36 tests across all 9 endpoints: oauth_disconnect, oauth_mode_get,
    oauth_mode_set, oauth_status, oauth_ping, oauth_token,
    oauth_request, oauth_managed_connect_start,
    oauth_managed_connect_poll). These handlers had no route-level
    unit tests since the migration — that gap predates #30257 but
    needed to close before the CLI dupes could be deleted.

DELETE outright (every top-level describe was describe.skip'd against
pre-IPC in-process logic that no longer exists):
  - 9 × assistant/src/cli/commands/oauth/__tests__/*.test.ts
    (connect, disconnect, mode, ping, status, token,
     providers-{register,update,delete})
  - assistant/src/__tests__/credentials-cli.test.ts (1232 lines)
  - assistant/src/cli/commands/__tests__/routes.test.ts (576 lines)

TRIM down to passing CLI-plumbing tests only:
  - oauth-cli.test.ts: 2103 → 135 lines (kept requirePlatformConnection)
  - usage-cli.test.ts: 153 → 85 lines (kept invalid-arg validation)
  - inference-send.test.ts: 643 → 236 lines (kept help text +
    no-message guard + --max-tokens validation)

Net: 15 files changed, +797 / -9910.

Coverage check: the underlying business logic that the deleted tests
nominally covered already runs through oauth-store.test.ts,
credential-vault.test.ts, oauth-apps-routes.test.ts,
oauth-providers-routes.test.ts, oauth-connect-routes.test.ts, and
usage-routes.test.ts. The new oauth-commands-routes.test.ts file
closes the only real coverage gap.

Follow-ups (not blocking, called out in file-level docstrings):
  - CLI plumbing tests for exitFromIpcResult exit-code mapping,
    shouldOutputJson/writeOutput formatting, and the oauth token
    shell-lockdown guard
  - IPC-mock-based tests for the trimmed inference-send / usage
    paths if anyone wants stronger end-to-end coverage

🔥 Generated with [Credence](https://vellum.ai)

Co-authored-by: credence-the-bot <credence-the-bot@users.noreply.github.com>
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