Skip to content

feat: add Command Code OAuth provider - #1066

Merged
Wibias merged 27 commits into
lidge-jun:devfrom
dbc-hbin:feat/command-code-auth
Aug 6, 2026
Merged

feat: add Command Code OAuth provider#1066
Wibias merged 27 commits into
lidge-jun:devfrom
dbc-hbin:feat/command-code-auth

Conversation

@dbc-hbin

@dbc-hbin dbc-hbin commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add the direct Command Code OAuth adapter with CLI-auth import and browser authorization
  • discover models dynamically from the authenticated provider catalog, without a static model fallback
  • expose generic provider accounts, usage, and catalog integration

Validation

  • bun run test
  • cd g ui && bun test tests && bun run lint && bun run lint:i18n && bun run build
  • bun run typecheck
  • bun run privacy:scan
  • live local Command Code request through OpenCodex

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I fixed all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

New Features

  • Added Command Code as a supported AI provider.
  • Added browser-based account login, credential refresh, and optional local CLI credential import.
  • Added account-specific live model discovery after login.
  • Added streaming chat responses with text, reasoning, tool calls, usage, and completion events.
  • Added workspace metadata, model aliases, configurable reasoning efforts, extended output limits, and resilient request handling.
  • Added localized Command Code branding and provider icons.

Documentation

  • Updated provider guides to describe authentication and account-specific model discovery.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review readiness checklist

This PR is kept in draft until every requirement below is fulfilled. The tickable checklist has been added to your PR description — tick all four boxes there.

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I fixed all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

All four boxes are ticked.
Completed against head 2264415; new commits after this will reset the checklist.
This pull request has been marked Ready for Review.
Maintainers notified: @lidge-jun @Ingwannu @Wibias

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR quality gates passed

This pull request now targets dev with acceptable ancestry, description, and UI screenshot coverage. The review readiness checklist is complete.

The title was left unchanged. Its existing draft status has been preserved.

@github-actions
github-actions Bot marked this pull request as draft August 5, 2026 15:39
@github-actions github-actions Bot added enhancement New feature or request intake: hygiene-blocked Deterministic PR hygiene checks failed labels Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@coderabbitai

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@Wibias

This comment was marked as outdated.

…data

- Preserve tool-result image parts as [image] markers instead of silently
  dropping them (contentPartsToText), matching other adapters.
- Bind the OAuth callback on both IPv4 and IPv6 loopback and race the shared
  manual-paste fallback (raw API key or pasted callback JSON/URL), matching
  OAuthCallbackFlow behavior for Windows/headless/remote cases.
- Minimize workspace metadata: cap the directory listing at 64 entries,
  bound the x-project-slug header, and drop the always-empty git stubs.
- Update providers docs (EN + ja/ko/ru/zh) and the registry note to describe
  OAuth login with local CLI credential import.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@Wibias Wibias added the maintainer-sponsored Maintainer sponsors this change to an auth, workflow, release, or dependency surface label Aug 5, 2026
@github-actions github-actions Bot removed the intake: hygiene-blocked Deterministic PR hygiene checks failed label Aug 5, 2026
@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

coderabbitai[bot]

This comment was marked as resolved.

…streaming

- Carry tool-result image parts in a follow-up user message (the proprietary
  tool-result output is text-only), so view_image data reaches the model
  instead of being dropped or flattened to a marker.
- Honor ctrl.signal during local CLI credential import (abort during whoami).
- Always stop callback servers even when controller callbacks throw.
- Bound the model-profile page read with readBoundedResponseBody.
- Cancel the NDJSON reader on teardown, send parsed.stream as the wire stream
  field, and emit a fallback done when a stream ends without a finish event.
- Add error-event, fallback-done, and stream-field tests; assert callback keys
  never leak into thrown errors.
- Fix the remaining "public catalog / unverifiable" claims in providers docs
  (EN + ja/ko/ru/zh) so they match the authenticated discovery wording.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@Wibias
Wibias marked this pull request as ready for review August 5, 2026 21:10
@Wibias

This comment was marked as resolved.

@github-actions
github-actions Bot marked this pull request as draft August 5, 2026 21:10
@github-actions
github-actions Bot marked this pull request as ready for review August 5, 2026 21:10
- Send memory as the schema-strict empty string instead of null.
- Treat finish-step as a terminal event (usage + finishReason) and emit only
  one done even when finish-step and finish both appear in the stream.
- Defensively strip SSE data: framing so a gateway shape drift cannot silently
  drop every event; raw newline-delimited JSON still parses as before.
- Make x-command-code-version configurable via provider.commandCodeVersion and
  update the default to the current CLI protocol version.
- Add finish-step and SSE-frame regression tests.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
chatgpt-codex-connector[bot]

This comment was marked as resolved.

Wibias and others added 5 commits August 6, 2026 00:37
The Command Code OAuth and API presets were only distinct in the provider
workspace; data-driven surfaces rendered the raw config id (command-code /
commandcode), so both still read as "Command Code". Route the provider id
through formatProviderDisplayName in:

- Models tab group headers and model tooltip
- Logs provider column, detail row, and attempt rows
- Usage per-model and per-provider tables
- API keys source label
- Dashboard active-providers table and dashboard models groups
- Combo target provider select

Route/path strings (e.g. command-code/model selects and cost breakdowns) keep
the raw id since it is the routing key and already disambiguates.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
command-code and commandcode differ by a single dash, so raw model routes
were still hard to tell apart. Add formatNamespacedModelId, which rewrites
the provider prefix of a provider/model route to its display name
(command-code/x -> "Command Code - Auth/x", commandcode/x -> "Command Code - API/x"),
and use it in the visible model-route surfaces:

- Models tab model rows and tooltip id
- Dashboard injection/shadow-call model selects
- Subagents delegation model select

The raw config id stays as the underlying value/key and in the Switch
aria-label; only the visible label changes.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
The Models page side rail under "Providers" still rendered the raw config
ids (command-code / commandcode). Route it and the custom-model modal title
through formatProviderDisplayName so both Command Code entries read as
"Command Code - Auth" / "Command Code - API" consistently.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Only the Models "Providers" side rail and custom-model modal title should show
the friendly display names; the collapsing provider group headers and the model
rows/tooltips inside stay as the raw config ids and namespaced routes, as they
were before.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
…ames

The Codex model picker (coding harness) lists routed models by their raw
slug, so the two Command Code presets were still `command-code/x` vs
`commandcode/x` — a single dash apart. For Command Code routed models only,
stamp the catalog display_name as `<registry label>/<model>` (e.g.
"Command Code - Auth/deepseek-v4-flash") so the harness picker distinguishes
them. The routing slug is untouched, other providers are unchanged, and a
configured user displayName still overrides the label.

Also route the Models-tab shadow-call model dropdown and the dashboard
injection/shadow-call/subagent delegation selects through the same friendly
label.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@Wibias
Wibias marked this pull request as ready for review August 5, 2026 23:20
@github-actions
github-actions Bot marked this pull request as draft August 5, 2026 23:20
@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Head commit changed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Wibias and others added 2 commits August 6, 2026 01:21
…h/api

Keep the raw config ids (command-code / commandcode) untouched so nothing
breaks, but relabel the model-picker/route display to the lowercase-dash
style the opencode presets use (opencode-free/x, opencode-go/x):

- GUI dropdowns and Models route labels: command-code/x -> commandcode-auth/x,
  commandcode/x -> commandcode-api/x
- Codex catalog display_name for Command Code routed models: same relabel;
  the routing slug is unchanged and other providers are untouched.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
…ng cards

- Drop the redundant vendor prefix in encoded Command Code model ids for
  display: command-code/deepseek-deepseek-v4-flash ->
  commandcode-auth/deepseek-v4-flash (GUI + Codex catalog display_name).
- Apply the friendly commandcode-auth/commandcode-api slugs to the Models
  tab collapsing group headers and model rows (not just the side rail), so
  the dropdowns in the screenshot are relabeled too.
- Add a providerDisplaySlug helper and tests for the de-dup behavior.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

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

Copy link
Copy Markdown

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: 3bbad09f9e

ℹ️ 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".

Comment thread src/providers/registry.ts
Comment thread src/adapters/command-code.ts Outdated
Comment thread src/types.ts
Wibias and others added 2 commits August 6, 2026 01:39
…, docs)

- Add mediaType to wire image parts (data URL parse + remote extension
  fallback) for /alpha/generate schema validation and gateway decoding.
- Mark the command-code adapter tool-capable in the routing capability path so
  profiles with require.tools stop excluding this provider.
- Preserve an operator's commandCodeVersion pin across login/add-account/reauth
  (upsertOAuthProvider no longer drops it).
- Let pasted JSON callback payloads through the shared manual-code gate for
  Command Code so the provider JSON parser is reachable in remote/headless
  logins.
- Iterate workspace entries with opendir and stop at the 64-entry cap instead
  of materializing every name.
- Update documented provider totals (69 -> 70, seven -> eight OAuth) across EN
  and ja/ko/ru/zh providers guides and quickstarts.

Declined with evidence: GLM effort refresh case-sensitivity — keyFor already
lowercases lookups against the lowercase table, verified against the live
catalog id (zai-org/GLM-5.2).

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@Wibias

Wibias commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

[GD] Verdict: gated (re-review)

PR: #1066 — feat: add Command Code OAuth provider
Head: 63568a0bdev (mergeable, draft)
Run: re-review of the 8 new Codex findings since the last review

Re-review summary

Fixed on 63568a0b (6 findings):

  • src/routing/capability.tscommand-code added to TOOL_CAPABLE_ADAPTERS, so routing no longer treats tool support as unknown for require.tools profiles.
  • src/adapters/command-code.ts — wire image parts now carry mediaType (data-URL parse + remote-extension fallback); workspace structure collected via opendir and stopped at the 64-entry cap instead of materializing every name.
  • src/oauth/index.ts — pasted JSON callback payloads pass the shared manual-code gate for command-code; commandCodeVersion pin preserved across login/add-account/reauth.
  • Docs — provider totals updated to 70 presets / eight OAuth in EN + ja/ko/ru/zh guides and quickstarts.

Declined with evidence (1 finding):

  • command-code-efforts.ts GLM effort refresh case-sensitivity — keyFor() already lowercases every lookup against the lowercase table; verified against the live catalog id zai-org/GLM-5.2. No change needed.

Validation: 221 provider/catalog tests pass, typecheck clean, GUI lint + i18n lint + privacy scan clean.

Remaining gates:

  • PR is 17 commits behind dev (base moved with GUI/routing PRs; none touch Command Code files). As a foreign PR this is an owner action: update feat/command-code-auth from the latest dev (or a maintainer can push the sync since it's cleanly mergeable).
  • Draft gate still active — the enforcer re-drafts on new commits.
  • Full CI matrix on 63568a0b awaits fork-PR approval.

Bottom line: All re-review findings are addressed (6 fixed, 1 declined with evidence, 1 duplicate). The PR is mergeable and code-clean; only the base-sync, draft, and CI-approval operational gates remain.

Full detail

Findings fixed

  1. Tool-capable routing signalcommand-code adapter added to TOOL_CAPABLE_ADAPTERS in src/routing/capability.ts. The adapter serializes params.tools and streams tool calls, but live /models rows carry no capabilities:["tools"] and parallelToolCalls is intentionally false, so routing treated tool support as unknown and could exclude this provider for require.tools profiles.
  2. Image mediaTypewireImagePart now emits { type, image, mediaType } per the /alpha/generate ModelMessage schema: data URLs parse their media type, remote URLs fall back to the extension. Applies to user-attachment image parts and the tool-result follow-up carrier.
  3. GUI paste JSON reachablesubmitManualLoginCode now admits a JSON object paste for command-code (which has no code param) so the provider-specific parsePastedCommandCodeInput JSON branch runs in remote/headless logins.
  4. commandCodeVersion pin preservedupsertOAuthProvider carries an existing pin into the rebuilt provider row; login/add-account/reauth no longer silently reverts to the compiled default.
  5. Bound directory enumerationcommandCodeConfig uses opendir and breaks at the 64-entry cap instead of readdir-materializing every name.
  6. Docs totals — 69→70 presets, seven→eight OAuth, EN + ja/ko/ru/zh guides and quickstarts.

Declined

  • GLM effort refresh case-sensitivity — false positive. commandCodeReasoningEfforts and refreshCommandCodeReasoningEfforts both route through keyFor() (trim + lowercase), and the effort table keys are already lowercase (zai-org/glm-5.2). Live catalog id zai-org/GLM-5.2 resolves correctly.

Validation

  • bun test tests/command-code-provider.test.ts tests/codex-catalog.test.ts tests/provider-registry-parity.test.ts tests/provider-workspace-data.test.ts — 221 pass
  • bun run typecheck — clean
  • GUI lint + lint:i18n — clean
  • bun run privacy:scan — passed

Owner actions (foreign PR)

  • Update the branch from the latest dev (17 commits behind; base commits are GUI/routing and do not touch Command Code files).
  • Mark ready for review after the sync + CI approval.

@github-actions
github-actions Bot marked this pull request as ready for review August 5, 2026 23:45
formatNamespacedModelId was title-casing every provider prefix (e.g.
fallback-provider -> Fallback Provider), breaking the Models page shadow-call
dropdown and its GUI test. Restrict the rewrite to the two Command Code ids
(commandcode-auth / commandcode-api); every other provider keeps its raw route.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@github-actions
github-actions Bot marked this pull request as draft August 5, 2026 23:57

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

Copy link
Copy Markdown

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: 920134efa5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread gui/src/provider-icons.ts Outdated
Comment thread src/adapters/command-code.ts Outdated
Comment thread src/adapters/command-code.ts
… lookup

- supportedCommandCodeEffort now maps both xhigh and ultra to the wire value
  max when the model's official ladder includes it, so an advertised ultra
  rung actually takes effect instead of silently dropping reasoning_effort.
- The effort lookup resolves compatibility ids (deepseek-v4-flash / glm-5.2)
  to their canonical Command Code id first, so legacy/migrated configs keep
  their reasoning behavior.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@Wibias
Wibias marked this pull request as ready for review August 6, 2026 00:14
@github-actions
github-actions Bot marked this pull request as draft August 6, 2026 00:15
@github-actions
github-actions Bot marked this pull request as ready for review August 6, 2026 00:17
@Wibias

Wibias commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Thanks @hanbinnoh — merging this.

Why it helps: this adds Command Code as a first-class provider with OAuth login (local CLI credential import), live model discovery from the authenticated catalog, a streaming adapter for the proprietary /alpha/generate wire, and full GUI support. Maintainer overtake resolved the review findings, conflicts, CI gates, and the two provider presets are now clearly distinguishable as commandcode-auth / commandcode-api.

@Wibias
Wibias merged commit ad38b5f into lidge-jun:dev Aug 6, 2026
7 checks passed

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

Copy link
Copy Markdown

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: 22644158ae

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +436 to +437
const stopReason = typeof event.rawFinishReason === "string" ? event.rawFinishReason : typeof event.finishReason === "string" ? event.finishReason : undefined;
yield { type: "done", usage: usage(usageValue), stopReason };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Normalize Command Code finish reasons

When /alpha/generate finishes with provider-native reasons such as stop or length, this forwards them directly as AdapterEvent.stopReason. The bridge treats an absent stopReason as a clean final answer and only recognizes max_tokens/content_filter as incomplete, so normal stop responses lose final-answer phase inference and length truncations are reported as completed instead of incomplete. Map length to max_tokens and omit stopReason for normal/tool-call stops before yielding done.

Useful? React with 👍 / 👎.

Comment thread src/routing/capability.ts
"azure",
"kiro",
"mimo-free",
"command-code",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Make tool capability apply to live rows

Fresh evidence after the TOOL_CAPABLE_ADAPTERS fix: adding command-code here still only helps when catalogRow === undefined in the tools expression below. Once Command Code live discovery has written a catalog row without capabilities:["tools"], policy routing for require.tools or tool-bearing requests still sees tools as unknown and can exclude this provider, so the adapter-level signal needs to apply even when a catalog row exists without a positive tools flag.

Useful? React with 👍 / 👎.

<Select
value={shadowCall?.model ?? ""}
options={[{ value: "", label: "—" }, ...models.map(m => ({ value: m.id, label: `${m.provider}/${m.id}` }))]}
options={[{ value: "", label: "—" }, ...models.map(m => ({ value: m.id, label: formatNamespacedModelId(`${m.provider}/${m.id}`, t) }))]}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Save the selected shadow-call route

When the Dashboard overview shadow-call picker is used with both Command Code account/API rows, the label now shows a provider-qualified commandcode-* choice but the saved value is still only m.id. /api/shadow-call-settings persists that bare native id, and routeModel() resolves bare slash ids by provider order/defaults rather than the provider the user selected, so helper calls can be redirected to the wrong Command Code account/API provider; use the row's namespaced slug for the option value, as the Models page does.

AGENTS.md reference: gui/AGENTS.md:L10-L10

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request maintainer-sponsored Maintainer sponsors this change to an auth, workflow, release, or dependency surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants